前端需要展示一个三维模型,并接收数据实时更新模型。在dataease中插入网页控件。通过websocket与后端通信。
- 在unity中写三维模型及代码交互逻辑
由于unity发布为webGL后所有跟网络相关的代码都不能使用,因此不能直接在unity的script中定义网络通信相关代码(可以测试使用,但打包成webGL后就没办法使用了)。在webGL的script关键只需要留下一个自定义函数。
//inputdata为参数,就是接收的数据格式,通过split函数分割后驱动模型gameObject
public void updateModel(string inputdata){
......
}
发布为webGL后,会生成一个文件夹,我的webGL发布生成的文件夹叫做mywebgl,文件结构为
-mywebgl
--build/
--TemplateData/
--index.html
- websokcet通信
由于webGL本身不支持网络通信,要想实现websocket通信需要自己写一个javascript代码并在发布的index.html引入。javascript代码用于实现websocket与后端进行通信,当后端发送数据至js代码时,js代码使用sendMessage函数发送至webgl。
- js代码msg.js
function buildWebSocket(unityInstance){
var socket = new WebSocket(`ws://${location.host}/myapi/ws`)
};
socket.onmessage = function(event) {
try{
msg =event.data;
unityInstance.SendMessage('daima','updateModel',msg)
}catch(e){
console.log(e)
}
}
sendMessage函数接收3个参数,第一参数为unity中定义绑定script的对象。第二个参数为script中定义的函数。第三个参数为发送至该函数的参数。
- 编辑index.html
首先引入需要的包,提前需要把需要的js文件放到指定位置
<script src = "./lib/webscoket/sockjs.min.js"></script>
<script src = "./lib/webscoket/sockjs.min.js"></script>
<script src="./msg.js"></script>
然后引入函数
我的是在110行左右
createUnityInstance(canvas,config,(progress)=>{
progressBraFull.style.width = 100 * progress +"%";
}).then((unityInstance) => {
buildWebSocket(unityInstance);
......
}
}
- dataease后端
在我写的dataease二次开发记录1中我介绍了如何只启动dataease并打开自己写的界面。
此处也是一样,将webGL发布生成的文件夹放入存放扩展文件的位置"D:\opt\dataease2.0\external/"。
websocket后端通信代码可以直接在dataease中写
WebSocketConfig.java
import com.example.datashow_backend.common.WSCode;
import com.example.datashow_backend.handler.MyWebSocketHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/myapi/ws").setAllowedOrigins("*");
}
}
MyWebSocketHandler.java
此处我写了线程模拟实际环境中定时发送数据至前端
public class MyWebSocketHandler extends TextWebSocketHandler {
private Thread sendThread = null;
@ResponseBody
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println( session.getRemoteAddress() + "连接已建立");
handleWs(session);
}
private void handleWs(WebSocketSession session){
sendThread = new Thread(new Runnable() {
@Override
public void run() {
Random random = new Random();
for (int i = 0; i < 100; i++) {
try {
float x = random.nextFloat();
session.sendMessage(new TextMessage(String.valueOf(x));
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
sendThread.start();
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("连接已关闭");
sendThread.stop();
}
}
最后启动后可通过链接访问
http://localhost:8100/external/mywebgl/index
打开后前端会执行buildWebSocket函数与后端建立连接,后端启动线程,每5秒钟发送一个随机数x至前端。前端收到x后执行socket.onmessage 函数,通过sendMessage函数发送x至unityInstance。unityInstance执行updateModel函数使模型动起来。