working communication between client and backend with message pack with working data flow

This commit is contained in:
ori agranat
2019-10-14 21:22:43 +03:00
parent 63290a07d3
commit 98a71aea66
6 changed files with 42 additions and 95 deletions

View File

@@ -240,7 +240,7 @@ public class VisionProcess implements Runnable {
point.put("fps", uiFps);
WebSend.put("point", point);
WebSend.put("raw_point", center);
ServerHandler.broadcastMessage(WebSend);
// ServerHandler.broadcastMessage(WebSend);
}
cameraProcess.updateFrame(streamOutputMat);

View File

@@ -1,9 +1,11 @@
package com.chameleonvision.web;
import com.chameleonvision.settings.GeneralSettings;
import com.chameleonvision.vision.Orientation;
import com.chameleonvision.vision.SortMode;
import com.chameleonvision.vision.TargetGroup;
import com.chameleonvision.vision.TargetIntersection;
import com.chameleonvision.vision.camera.Camera;
import com.chameleonvision.vision.camera.CameraException;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.vision.camera.CameraManager;
@@ -14,15 +16,8 @@ import edu.wpi.cscore.VideoException;
import io.javalin.websocket.*;
import org.apache.commons.lang3.ArrayUtils;
import org.eclipse.jetty.util.ArrayUtil;
import org.msgpack.core.MessagePack;
import org.msgpack.core.MessagePacker;
import org.msgpack.core.MessageUnpacker;
import org.msgpack.core.buffer.MessageBufferOutput;
import org.msgpack.jackson.dataformat.MessagePackFactory;
import org.msgpack.value.ImmutableArrayValue;
import org.msgpack.value.ImmutableValue;
import org.msgpack.value.Value;
import org.springframework.beans.BeanUtils;
import java.io.IOException;
import java.lang.reflect.Field;
@@ -55,95 +50,59 @@ public class ServerHandler {
try {
switch (entry.getKey()) {
case "generalSettings": {
System.out.println("asdds");
//change general settings using a general settings object
break;
}
case "cameraSettings": {
System.out.println("sadfsdf");
//change camera settings using a camera settings object
break;
}
case "command": {
System.err.println("not implemented");
// used to define all incoming commands
break;
}
case "currentCamera": {
//camera name by string
CameraManager.setCurrentCamera((String) entry.getValue());
HashMap<String,Object> tmp = new HashMap<>();
tmp.put("pipeline",CameraManager.getCurrentCamera().getCurrentPipeline());
broadcastMessage(tmp);
break;
}
case "currentPipeline": {
// camera pipeline by index
CameraManager.getCurrentCamera().setCurrentPipelineIndex((Integer) entry.getValue());
HashMap<String,Object> tmp = new HashMap<>();
tmp.put("pipeline",CameraManager.getCurrentCamera().getCurrentPipeline());
//TODO Add cam settings to the map
broadcastMessage(tmp);
break;
}
default: {//Change pipeline values
//Two special cases for exposure and brightness changes
if (entry.getKey().equals("exposure"))
try {
// CameraManager.getCurrentCamera().setExposure(value.asIntegerValue().toInt());
} catch (VideoException e) {
System.out.println("Exposure changes is not supported on your webcam/webcam's driver");
}
else if (entry.getKey().equals("brightness")) try {
// CameraManager.getCurrentCamera().setBrightness(value.asIntegerValue().toInt());
} catch (VideoException e) {
e.printStackTrace();
}
else
// setValue(CameraManager.getCurrentPipeline(), entry.getKey(), entry.getValue());//All of the other assignments fields
default: {
setField(CameraManager.getCurrentCamera().getCurrentPipeline(),entry.getKey(),entry.getValue());
break;
}
}
} catch (Exception e) {
e.printStackTrace();
// unexpectedData(key, value);
}
}
}
private void setValue(Object obj, String fieldName, ImmutableValue value) {
private void setField(Object obj, String fieldName, Object value) {
try {
boolean found = false;
Field[] fields = obj.getClass().getFields();
for (Field f : fields) {
if (f.getName().equals(fieldName)) {
found = true;
if (f.getType().isEnum())//Field is enum like Orientation
f.set(obj, f.getType().getEnumConstants()[value.asIntegerValue().toInt()]);
else if (value.isBooleanValue()) {//Field is boolean like erode
f.set(obj, value.asBooleanValue().getBoolean());
} else if (value.isIntegerValue()) {//Field is int like M and B
f.set(obj, value.asIntegerValue().toInt());
} else if (f.get(obj) instanceof List<?>) {
List<Value> valLst = ((ImmutableArrayValue) value).list();
if (((List) f.get(obj)).get(0).getClass().equals(Float.class)) {//Field is List of Floats like area in pipeline
List<Float> lst = new ArrayList<>();
for (Value v : valLst) {
lst.add(v.isFloatValue() ? v.asFloatValue().toFloat() : (float) v.asIntegerValue().toInt());//Adds float if value is float, casts value to float from int otherwise
}
f.set(obj, lst);
} else if (((List) f.get(obj)).get(0).getClass().equals(Integer.class)) {//Fields is List of Integers like hue in pipeline
List<Integer> lst = new ArrayList<>();
for (Value v : valLst) {
lst.add(v.asIntegerValue().toInt());
}
f.set(obj, lst);
}
}
}
Field field = obj.getClass().getField(fieldName);
if (BeanUtils.isSimpleValueType(field.getType())){
//if enum needs to convert
field.set(obj,value);
} else if(field.getType() == List.class){
field.set(obj,value);
}
if (!found)
unexpectedData(fieldName, value);
} catch (Exception e) {
System.out.println("Exception setting field");
e.printStackTrace();
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
}
}
public void unexpectedData(String key, ImmutableValue v) {
System.err.println("Unexpected key or value, key=" + key + " Value=" + v.toString());
//TODO send a error message to the user
//TODO in the very far future send a bug report?
}
private static void broadcastMessage(Object obj, WsContext userToSkip) {
if (users != null)
for (var user : users) {
@@ -163,35 +122,22 @@ public class ServerHandler {
broadcastMessage(obj, null);//Broadcasts the message to every user
}
private static Map<String, Object> allFieldsToMap(Object obj) {
Map map = new HashMap<String, Object>();
try {
Field[] fields = obj.getClass().getFields();
for (Field field : fields) {
map.put(field.getName(), field.get(obj));
}
} catch (IllegalAccessException e) {
System.err.println("Illegal Access error:" + e.getStackTrace());
}
return map;
}
public static void sendFullSettings() {
//General settings
Map<String, Object> fullSettings = new HashMap<>(allFieldsToMap(SettingsManager.GeneralSettings));
Map<String, Object> fullSettings = new HashMap<String, Object>();
fullSettings.put("settings", SettingsManager.GeneralSettings);
fullSettings.put("cameraList", CameraManager.getAllCamerasByName().keySet());
try {
var currentCamera = CameraManager.getCurrentCamera();
fullSettings.putAll(allFieldsToMap(currentCamera.getCurrentPipeline()));
fullSettings.put("pipeline",currentCamera.getCurrentPipeline());
fullSettings.put("pipelineList", currentCamera.getPipelines().keySet());
fullSettings.put("resolutionList", CameraManager.getResolutionList());
fullSettings.put("resolution", currentCamera.getVideoModeIndex());
fullSettings.put("FOV", currentCamera.getFOV());
fullSettings.put("port", currentCamera.getStreamPort());
} catch (CameraException e) {
System.err.println("No camera found!");
//TODO: add message to ui to inform that there are no cameras
}
// broadcastMessage(fullSettings);
broadcastMessage(fullSettings);
}
}

View File

@@ -24,6 +24,7 @@
</template>
<script>
import { async } from 'q';
export default {
name: 'App',
@@ -51,13 +52,13 @@ export default {
}),
created(){
this.$options.sockets.onmessage = (data) =>{
this.$options.sockets.onmessage = async (data) =>{
try{
let info = new Uint8Array(data.data.substring(1, data.data.length-1).split(","));//Converts incoming data to data that msgpack can decode
let message = this.$msgPack().decode(info);
var buffer = await data.data.arrayBuffer();
let message = this.$msgPack.decode(buffer);
for(let prop in message){
if(message.hasOwnProperty(prop)){
console.log(message);
this.handleMessage(prop, message[prop]);
}
}
}

View File

@@ -9,11 +9,11 @@ import msgPack from 'msgpack5';
Vue.config.productionTip = false;
// Vue.use(VueNativeSock,'ws://' + location.host + '/websocket',{format: 'json'});
Vue.use(VueNativeSock,'ws://'+location.hostname+':8888/websocket');
Vue.prototype.$msgPack = msgPack;
Vue.prototype.$msgPack = msgPack(true)
Vue.mixin({
methods:{
handleInput(key,value){
let msg = this.$msgPack().encode({[key]:value})
let msg = this.$msgPack.encode({[key]:value})
this.$socket.send(msg);
}
}

View File

@@ -34,7 +34,7 @@ export default new Vuex.Store({
currentCameraIndex:0,
currentPipelineIndex:0,
cameraList:[],
pipelinelist:[],
pipelineList:[],
point:{}
},
mutations: {
@@ -46,7 +46,7 @@ export default new Vuex.Store({
currentCameraIndex: set('currentCameraIndex'),
currentPipelineIndex: set('currentPipelineIndex'),
cameraList: set('cameraList'),
pipelinelist: set('cameraList'),
pipelineList: set('pipelineList'),
point:set('point')
},
actions: {
@@ -58,7 +58,7 @@ export default new Vuex.Store({
currentCameraIndex: state =>state.currentCameraIndex,
currentPipelineIndex: state =>state.currentPipelineIndex,
cameraList: state =>state.cameraList,
pipelinelist: state =>state.pipelinelist,
pipelineList: state =>state.pipelineList,
point: state =>state.point,
setPipeValues(state,obj){
for(let i in obj){

View File

@@ -143,7 +143,7 @@ import CVicon from '../components/cv-icon'
},
pipelineList:{
get(){
return this.$store.state.pipelinelist;
return this.$store.state.pipelineList;
}
},
pipeline:{