WebSocket接收前端图片自动断开连接异常
- 项目结构
- 代码
@Slf4j@Component@ServerEndpoint("/echo/{sid}")public class WebSocketServer { /** * concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象 */ private static CopyOnWriteArraySetWebSocketServer webSocketSet = new CopyOnWriteArraySet(); /** * 与某个客户端的连接会话,需要通过它来给客户端发送数据 */ private Session session; /** * 连接会话id */ private String sid = ""; /** * 连接建立成功调用的方法 * * @param session 会话 * @param sid 标识连接的id */ @OnOpen public void onOpen(Session session, @PathParam("sid") String sid) { this.session = session; this.sid = sid; // 加入set中 webSocketSet.add(this); log.info("【websocket消息】有新的连接, 总数:{}", webSocketSet.size()); try { sendMessage("连接成功"); } catch (IOException e) { log.error("websocket IO异常"); } } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息(字符串) */ @OnMessage public void onMessage(String message) throws IOException { log.info("【websocket消息】收到客户端{}发来的字符串消息:{}", sid, message); sendMessage(message); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息(字节数组) */ @OnMessage public void onMessage(byte[] message) throws IOException { log.info("收到图片了"); String str = Base64.encodeBase64String(message); // 图片base64 log.info(str.substring(0, 100)); } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { // 从set中删除 webSocketSet.remove(this); log.info("【websocket消息】连接断开, 总数:{}", webSocketSet.size()); } /** * 连接发生错误时调用的方法 * * @param error 运行时抛出的异常 */ @OnError public void onError(Throwable error) { log.error("【websocket消息】发生错误"); error.printStackTrace(); } /** * 服务器主动推送字符串消息 * * @param message 服务器发送到前端的消息 * @throws IOException IO异常 */ private void sendMessage(String message) throws IOException { session.getBasicRemote().sendText(message); } /** * 服务器主动推送二进制消息 * * @param message 服务器发送到前端的消息 * @throws IOException IO异常 */ private void sendMessage(byte[] message) throws IOException { ByteBuffer byteBuffer = ByteBuffer.wrap(message); session.getBasicRemote().sendBinary(byteBuffer); }}
- 前端
!DOCTYPE htmlhtml lang="en" head meta charset="UTF-8" title发送二进制消息/title script var websocket = null; // 判断当前浏览器是否支持WebSocket if ('WebSocket' in window) { websocket = new WebSocket("ws://localhost:8080/echo/65"); // websocket默认是传输字符串的,需要改为arraybuffer二进制传输类型 websocket.binaryType = "arraybuffer"; } else { alert('当前浏览器 Not support websocket') } // 连接发生错误的回调方法 websocket.onerror = function () { setMessageInnerHTML("WebSocket连接发生错误"); }; // 连接成功建立的回调方法 websocket.onopen = function () { setMessageInnerHTML("WebSocket连接成功"); }; // 接收到消息的回调方法 websocket.onmessage = function (event) { // 将接收到的二进制数据转为字符串 var unit8Arr = new Uint8Array(event.data); setMessageInnerHTML(byteToString(unit8Arr)); }; // 连接关闭的回调方法 websocket.onclose = function () { setMessageInnerHTML("WebSocket连接关闭"); }; // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function () { closeWebSocket(); }; function setMessageInnerHTML(innerHTML) { document.getElementById('message').innerHTML += innerHTML + 'br/'; } //关闭WebSocket连接 function closeWebSocket() { websocket.close(); } /** * 网络图像文件转Base64 */ function getBase64Image(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, img.width, img.height); var ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase(); var dataURL = canvas.toDataURL("image/" + ext); console.log(dataURL); return dataURL; } /** *Base64字符串转二进制 */ function dataURLtoBlob(dataurl) { var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); } // 发送图片 function sendPic() { var image = new Image(); image.src = "liu.jpeg"; image.onload = function () { //这样就获取到了文件的Base64字符串 var base64 = getBase64Image(image); //Base64字符串转二进制 var file = dataURLtoBlob(base64); websocket.send(file); } } //将字符串转为 Array byte数组 function stringToByte(str) { var bytes = []; var len, c; len = str.length; for (var i = 0; i len; i++) { c = str.charCodeAt(i); if (c = 0x010000 && c = 0x10FFFF) { bytes.push(((c 18) & 0x07) | 0xF0); bytes.push(((c 12) & 0x3F) | 0x80); bytes.push((
版权声明
即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。