Java使用WebSocket发送消息后前端无法收到的坑与解决办法

一、前言

最近在把后台Golang版的WebSocket项目修改为Java版的WebSocket项目;由于没有Golang的代码,只能自己想办法硬猜该怎么写。

在踩了一堆坑后,终于基本写完了。以下是踩坑总结与解决办法。

二、问题描述

1.前后台的WebSocket通信,传递的是字节数组(byte[]),而不是String。

2.因此,后台使用wsSession.getAsyncRemote().sendText(string)给前台发送消息的话,前台会报错,无法解析。

3.后台尝试用ByteBuffer对象装入需要发送的消息,使用wsSession.getAsyncRemote().sendBinary(byteBuffer)发送给前台消息,但是前台vconsole中没有任何反应,似乎是没有收到消息。

4.后台尝试增加wsSession.getAsyncRemote().flushBatch()方法,这个方法看起来类似flush()方法,但是会报错,不能使用。

5.后台尝试使用wsSession.getBasicRemote().sendBinary(byteBuffer)方法,但是前台vconsole还是没有反应,似乎是没有收到消息。

6.后台尝试增加wsSession.getBasicRemote().flushBatch()方法,这个方法看起来类似BasicRemote的flush()方法,但是会报错,还是不能使用。

7.后台发现,如果用getBasicRemote()的话,可以拿到输出流对象,OutputStream os = wsSession.getBasicRemote().getSendStream()

8.于是,后台这样写,但是前端还是收不到消息:

OutputStream os = wsSession.getBasicRemote().getSendStream();
os.write(byteBuffer.array());
os.flush();

三、解决办法

经过多次尝试发现,Java发送webSocket的字节数组信息给前端时,只增加flush()是不够的,必须增加close(),前端才能收到消息。代码样例如下:

OutputStream os = wsSession.getBasicRemote().getSendStream();
os.write(byteBuffer.array());
os.flush();
os.close();

四、总结

1.Java通过WebSocket发送消息给前端,网上一般用这个方法:

wsSession.getAsyncRemote().sendText(string);

发送String类型的消息应该没有问题,但是如果用类似的方法wsSession.getAsyncRemote().sendBinary(byteBuffer);,发送字节数组时,就会有问题,前端总是收不到消息(不知道怎么flush)。

2.经过测试,如果要给前端发送字节数组,最好还是用OutputStream os = wsSession.getBasicRemote().getSendStream()获得BasicRemote的输出流(AsyncRemote无法获得输出流),然后write()写消息,最后close()关闭流,前端就可以收到消息了。

五、其它

虽然没有Golang代码,但是还好有前端的js代码,通过查看js代码梳理出了主要流程,然后用Java实现了之前Golang的WebSocket的功能。

以下是js相关总结:
1.then()方法,会在上一个方法执行完毕后,才执行then()方法中的内容。

2.对于Promise方法,如果其后有then方法,那么只有当Promise方法的resolve()方法被执行,才说明Promise方法执行完毕,才会走后续的then方法。

3.如果Promise方法的reject()方法被执行,那么会报错,不会继续走then()方法;如果外层有try-catch,那么就会进入catch方法。

4.如果Promise方法的resolve(o)方法中包含参数o,那么这个参数o可以传递给后续的then方法。

5.Promise.race方法的意思是,其中可以写一个方法数组,这个方法数组中可以有多个方法,这些方法都会执行,采用赛跑(race)模式,如果哪个方法先执行完毕,就采用这个方法的结果。

6.关于EventEmitter,可以使用.on(key,function)方法注册一个触发器;后续使用.emit(key,obj)方法,可以触发key一致的function方法,obj则可以当做参数传递给function方法。

7.js中,websocket的消息监听方法样例为

this.websocket.addEventListener('message',this._function);

如果用到了websocket,总是可以搜索到这一句的(外面找不到的话,可以找找node_modules里面)。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是一个简单的 WebSocket 示例,包含 Java 后端发送 JSON 数据和前端 JavaScript 接收 JSON 数据的代码。 Java 后端代码: ```java import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import org.json.JSONObject; @ServerEndpoint("/websocket") public class WebSocketServer { @OnOpen public void onOpen(Session session) { System.out.println("Connected ... " + session.getId()); } @OnMessage public void onMessage(String message, Session session) { System.out.println("Received message: " + message); JSONObject jsonObject = new JSONObject(); jsonObject.put("name", "John"); jsonObject.put("age", 30); jsonObject.put("city", "New York"); session.getAsyncRemote().sendText(jsonObject.toString()); } @OnClose public void onClose(Session session) { System.out.println("Disconnected ... " + session.getId()); } @OnError public void onError(Throwable t) { t.printStackTrace(); } } ``` JavaScript 前端代码: ```javascript var websocket = new WebSocket("ws://localhost:8080/websocket"); websocket.onopen = function(event) { console.log("Connected ... "); var message = { "type": "hello", "message": "Hello, server!" }; websocket.send(JSON.stringify(message)); }; websocket.onmessage = function(event) { console.log("Received message: " + event.data); var data = JSON.parse(event.data); console.log("Name: " + data.name); console.log("Age: " + data.age); console.log("City: " + data.city); }; websocket.onclose = function(event) { console.log("Disconnected ... "); }; websocket.onerror = function(error) { console.error("Error: " + error); }; ``` 这个示例中,后端在收到客户端发送消息后,创建了一个 JSON 对象,并把它发送给客户端;前端在接收到服务端发送消息后,把字符串转换成 JSON 对象,并打印出其中的属性值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想永不停

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值