具有服务器功能的 WebPack 项目
WebPack project with server functionality
http://wiki.bitplan.com/index.php/Dash describes the Car simulation software https://github.com/mattbradley/dash which I am forking to integrate it with https://github.com/rc-dukes/dukes as asked for in https://github.com/rc-dukes/dukes/issues/37.
目标是将驱动程序图像发送到 rc-dukes 软件,并允许通过 vert.x 总线命令从 rc-dukes 控制模拟器中的运动。
当与 "real" 汽车交谈时 - 此时图像通过 http 作为 mjpeg 流传输。
现在 Dash 是一个基于 webpack 的项目,因此被设计为 运行 作为浏览器中的客户端,甚至来自 file:// 协议。
我现在想创建一个具有 Web 服务器功能并使用 vert.x 与 rc-dukes 项目的其余部分通信的版本。
首先,我误以为简单地添加一个 WebServer 并使用 require http 和 fs,这导致了很多关于如何将节点与 WebServer 集成的问题 - 最后这似乎不是一个好的途径去吧,因为它会打破底层破折号项目的最初想法。
现在我想 "optionally" 在项目中有服务器功能。
将项目拆分为服务器/客户端版本似乎不是一个好主意。
您将在 https://github.com/rc-dukes/dash/commit/ea616a38 找到相关的当前提交
相关行
// import WebServer from "./remote/WebServer"
//this.videoServer=new WebServer(8234);
//this.videoServer.start()
目前已被注释掉
更好的设计是什么?
我的假设是,简单地通过 vert.x 发送图像是最好的选择。
Verticle 方法效果很好。
心跳和发送图片的回调
/**
* call back when a vert.x heartbeat is received
* @param self - the true this pointer for class Simulator
* @param heartBeatCount - the number of heart beats received so far
*/
onHeartBeat(self,heartBeatCount) {
var color=heartBeatCount/3%2==0?"white":"purple";
self.setColorAndTitle("heartbeat-icon",color,heartBeatCount.toString());
// reply with the current image
self.onSendImage(self);
}
/**
* call back to send current Three.js canvas over the vert.x wire
* @param self - the true this pointer for class Simulator
*/
onSendImage(self) {
//
var strMime = "image/jpeg";
var imgData = this.renderer.domElement.toDataURL(strMime);
self.remoteController.sendImage(imgData);
}
Vert.x javascript 与 Java 服务器端通信的 Verticle
// part of https://github.com/rc-dukes/dash fork of https://github.com/mattbradley/dash
const CALLSIGN_FLASH = "Velvet ears"; // Watchdog
const CALLSIGN_BO = "Lost sheep Bo"; // Car
const CALLSIGN_ROSCO = "Red Dog"; // Debug ImageView server
var simulatorVerticle = null;
/**
* SimulatorVerticle to be used as remoteController
*/
export default class SimulatorVerticle {
/**
* construct me
* @param busUrl
* @param self
* @param onHeartBeat
*/
constructor(busUrl,self=null,onHeartBeat=null) {
this.busUrl=busUrl;
this.self=self;
this.onHeartBeat=onHeartBeat;
this.heartBeatCount=0;
this.debugHeartBeat=true;
this.remoteControl=new RemoteControl();
simulatorVerticle=this;
this.enabled=false;
}
/**
* all publish messages should go thru this function
*
* @param address
* @param message
* @param headers
*/
publish(address,message,headers) {
if (this.eb.state===EventBus.OPEN)
this.eb.publish(address, message, headers);
};
/**
* send the given image to the debug image server
* @param imgData
*/
sendImage(imgData) {
this.publish(CALLSIGN_ROSCO+":SIMULATOR_IMAGE",imgData);
}
/**
* start the verticle and register the handlers
*/
start() {
if (!this.eb) {
this.eb = new EventBus(this.busUrl);
this.eb.onopen = function() {
simulatorVerticle.eb.registerHandler(CALLSIGN_FLASH,simulatorVerticle.heartBeatHandler);
simulatorVerticle.eb.registerHandler(CALLSIGN_BO,simulatorVerticle.carMessageHandler)
};
};
this.enabled=true;
}
stop() {
if (this.eb)
this.eb.close();
this.eb=null;
this.enabled=false;
}
/**
* handle a car message
* @param err - potential errors
* @param msg - the vert.x message
*/
carMessageHandler(err,msg) {
var carjo=msg.body;
console.log(JSON.stringify(carjo));
var sv=simulatorVerticle;
switch (carjo.type) {
case 'servodirect':
if (carjo.position) {
// the position can be between -100 and 100
var pos=parseFloat(carjo.position);
// we need a value between -1 and +1
sv.remoteControl.steer=pos/100;
}
break;
case 'servo':
switch (carjo.position) {
case 'left':
sv.remoteControl.steer-=0.01;
break;
case 'right':
sv.remoteControl.steer+=0.01;
break;
case 'center':
sv.remoteControl.steer=0;
break;
}
break;
case 'motor':
switch (carjo.speed) {
case 'up':
sv.remoteControl.gas+=0.01;
break;
case 'down':
sv.remoteControl.gas-=0.01;
break;
case 'brake':
sv.remoteControl.break+=0.01;
break;
case 'stop':
sv.remoteControl.gas=0;
sv.remoteControl.break=1;
break;
}
break;
}
}
/**
* handle a heart beat message
* @param err - potential errors
* @param msg - the vert.x message
*/
heartBeatHandler(err,msg) {
var jo=msg.body;
var sv=simulatorVerticle;
if (sv.debugHeartBeat)
console.log(JSON.stringify(jo));
sv.heartBeatCount++;
if (sv.onHeartBeat && sv.self) {
sv.onHeartBeat(sv.self,sv.heartBeatCount);
}
}
stateColor() {
var stateColor = "white";
if (this.eb) {
switch (this.eb.state) {
case EventBus.CONNECTING:
stateColor = "orange";
break;
case EventBus.OPEN:
stateColor = "green";
break;
case EventBus.CLOSING:
stateColor = "orange";
break;
case EventBus.CLOSED:
stateColor = "red";
break;
}
} else {
stateColor = "violet";
}
return stateColor;
}
}
export class RemoteControl {
/**
* @param gas
* @param brake
* @param steer
*/
constructor(gas=0,brake=0,steer=0) {
this.gas=0;
this.brake=0;
this.steer=0;
}
}
http://wiki.bitplan.com/index.php/Dash describes the Car simulation software https://github.com/mattbradley/dash which I am forking to integrate it with https://github.com/rc-dukes/dukes as asked for in https://github.com/rc-dukes/dukes/issues/37.
目标是将驱动程序图像发送到 rc-dukes 软件,并允许通过 vert.x 总线命令从 rc-dukes 控制模拟器中的运动。
当与 "real" 汽车交谈时 - 此时图像通过 http 作为 mjpeg 流传输。
现在 Dash 是一个基于 webpack 的项目,因此被设计为 运行 作为浏览器中的客户端,甚至来自 file:// 协议。
我现在想创建一个具有 Web 服务器功能并使用 vert.x 与 rc-dukes 项目的其余部分通信的版本。
首先,我误以为简单地添加一个 WebServer 并使用 require http 和 fs,这导致了很多关于如何将节点与 WebServer 集成的问题 - 最后这似乎不是一个好的途径去吧,因为它会打破底层破折号项目的最初想法。
现在我想 "optionally" 在项目中有服务器功能。
将项目拆分为服务器/客户端版本似乎不是一个好主意。
您将在 https://github.com/rc-dukes/dash/commit/ea616a38 找到相关的当前提交 相关行
// import WebServer from "./remote/WebServer"
//this.videoServer=new WebServer(8234);
//this.videoServer.start()
目前已被注释掉
更好的设计是什么?
我的假设是,简单地通过 vert.x 发送图像是最好的选择。
Verticle 方法效果很好。
心跳和发送图片的回调
/**
* call back when a vert.x heartbeat is received
* @param self - the true this pointer for class Simulator
* @param heartBeatCount - the number of heart beats received so far
*/
onHeartBeat(self,heartBeatCount) {
var color=heartBeatCount/3%2==0?"white":"purple";
self.setColorAndTitle("heartbeat-icon",color,heartBeatCount.toString());
// reply with the current image
self.onSendImage(self);
}
/**
* call back to send current Three.js canvas over the vert.x wire
* @param self - the true this pointer for class Simulator
*/
onSendImage(self) {
//
var strMime = "image/jpeg";
var imgData = this.renderer.domElement.toDataURL(strMime);
self.remoteController.sendImage(imgData);
}
Vert.x javascript 与 Java 服务器端通信的 Verticle
// part of https://github.com/rc-dukes/dash fork of https://github.com/mattbradley/dash
const CALLSIGN_FLASH = "Velvet ears"; // Watchdog
const CALLSIGN_BO = "Lost sheep Bo"; // Car
const CALLSIGN_ROSCO = "Red Dog"; // Debug ImageView server
var simulatorVerticle = null;
/**
* SimulatorVerticle to be used as remoteController
*/
export default class SimulatorVerticle {
/**
* construct me
* @param busUrl
* @param self
* @param onHeartBeat
*/
constructor(busUrl,self=null,onHeartBeat=null) {
this.busUrl=busUrl;
this.self=self;
this.onHeartBeat=onHeartBeat;
this.heartBeatCount=0;
this.debugHeartBeat=true;
this.remoteControl=new RemoteControl();
simulatorVerticle=this;
this.enabled=false;
}
/**
* all publish messages should go thru this function
*
* @param address
* @param message
* @param headers
*/
publish(address,message,headers) {
if (this.eb.state===EventBus.OPEN)
this.eb.publish(address, message, headers);
};
/**
* send the given image to the debug image server
* @param imgData
*/
sendImage(imgData) {
this.publish(CALLSIGN_ROSCO+":SIMULATOR_IMAGE",imgData);
}
/**
* start the verticle and register the handlers
*/
start() {
if (!this.eb) {
this.eb = new EventBus(this.busUrl);
this.eb.onopen = function() {
simulatorVerticle.eb.registerHandler(CALLSIGN_FLASH,simulatorVerticle.heartBeatHandler);
simulatorVerticle.eb.registerHandler(CALLSIGN_BO,simulatorVerticle.carMessageHandler)
};
};
this.enabled=true;
}
stop() {
if (this.eb)
this.eb.close();
this.eb=null;
this.enabled=false;
}
/**
* handle a car message
* @param err - potential errors
* @param msg - the vert.x message
*/
carMessageHandler(err,msg) {
var carjo=msg.body;
console.log(JSON.stringify(carjo));
var sv=simulatorVerticle;
switch (carjo.type) {
case 'servodirect':
if (carjo.position) {
// the position can be between -100 and 100
var pos=parseFloat(carjo.position);
// we need a value between -1 and +1
sv.remoteControl.steer=pos/100;
}
break;
case 'servo':
switch (carjo.position) {
case 'left':
sv.remoteControl.steer-=0.01;
break;
case 'right':
sv.remoteControl.steer+=0.01;
break;
case 'center':
sv.remoteControl.steer=0;
break;
}
break;
case 'motor':
switch (carjo.speed) {
case 'up':
sv.remoteControl.gas+=0.01;
break;
case 'down':
sv.remoteControl.gas-=0.01;
break;
case 'brake':
sv.remoteControl.break+=0.01;
break;
case 'stop':
sv.remoteControl.gas=0;
sv.remoteControl.break=1;
break;
}
break;
}
}
/**
* handle a heart beat message
* @param err - potential errors
* @param msg - the vert.x message
*/
heartBeatHandler(err,msg) {
var jo=msg.body;
var sv=simulatorVerticle;
if (sv.debugHeartBeat)
console.log(JSON.stringify(jo));
sv.heartBeatCount++;
if (sv.onHeartBeat && sv.self) {
sv.onHeartBeat(sv.self,sv.heartBeatCount);
}
}
stateColor() {
var stateColor = "white";
if (this.eb) {
switch (this.eb.state) {
case EventBus.CONNECTING:
stateColor = "orange";
break;
case EventBus.OPEN:
stateColor = "green";
break;
case EventBus.CLOSING:
stateColor = "orange";
break;
case EventBus.CLOSED:
stateColor = "red";
break;
}
} else {
stateColor = "violet";
}
return stateColor;
}
}
export class RemoteControl {
/**
* @param gas
* @param brake
* @param steer
*/
constructor(gas=0,brake=0,steer=0) {
this.gas=0;
this.brake=0;
this.steer=0;
}
}