上一篇我们说了一下websocket的基本概念及简单案例,本篇是一个案例,传输文本类型的文件,可以稍微扩展成大文件上传
前端代码
<template> <div> 连接地址: <input type="text" id="conn" placeholder="ws://tmp.server.com:port/socket" v-model="connAddress"/> <button v-on:click="click">连接</button> <div> <textarea v-model="msg"></textarea> <button v-on:click="webSocketSend">发送文本消息</button> </div> 接收到的文本消息: <div> <textarea v-model="receive"></textarea> </div> <!--------------------发送文件----------------------------------------------------> <!--大文件上传的话,无非就是根据文件的大小进行切分,然后固定每次传输多少字节,然后再服务端进行合并,自己实现吧--> <div> <input type="file" @change="webSocketSendFile"/> </div> <!--img 用来显示服务端发送的图片--> 收到的图片:<img :src="img" alt=""> </div> </template> <script> export default { name: 'websocket', data() { return { connAddress: 'ws://localhost:8081/socket', msg: '', webSocket: null, receive: '', img: '', file: '' } }, created() { // this.initWebSocket(); }, destroyed() { this.webSocket.close() //离开路由之后断开websocket连接 }, methods: { click() { this.initWebSocket(); }, initWebSocket() { this.webSocket = new WebSocket(this.connAddress); this.webSocket.onopen = this.webSocketOnOpen(); this.webSocket.onmessage = this.webSocketOnMessage; this.webSocket.onopen = this.webSocketOnOpen; this.webSocket.onerror = this.webSocketOnError; this.webSocket.onclose = this.webSocketClose; }, webSocketOnOpen(event) { //连接建立之后执行send方法发送数据 console.log('连接建立', event); }, webSocketOnError(event) {//连接建立失败重连 console.log('失败', event); this.initWebSocket(); }, webSocketOnMessage(event) { //数据接收 //把 event 打印出来 看看里面都有什么东西 console.log('数据接收', event); //如果是图片类型,则显示图片 if (event.data instanceof Blob){ const src = window.URL.createObjectURL(event.data); this.img = src; }else {//文本信息直接输出 this.receive = event.data; } }, webSocketClose(event) { //关闭 console.log('断开连接', event); }, webSocketSend() {//数据发送 console.log(this.msg) this.webSocket.send(this.msg); }, webSocketSendFile(e) {//文件数据发送 let files = e.target.files; console.log(files) let blob = files[0].slice(0, files[0].size); this.webSocket.send(blob); }, } } </script> <style scoped> #conn { width: 30%; } textarea { width: 30%; height: 50px; } </style>后端代码
@Configuration public class WebSocketConfig implements ServletContextInitializer { /** * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint * @return */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } @Override public void onStartup(ServletContext servletContext) { servletContext.addListener(WebAppRootListener.class); servletContext.setInitParameter("org.apache.tomcat.websocket.textBufferSize","51200000"); servletContext.setInitParameter("org.apache.tomcat.websocket.binaryBufferSize","51200000"); } } @ServerEndpoint("/socket") @Component @Slf4j public class WebSocketEndpoint { public WebSocketEndpoint() { log.info("构造方法执行:" + this.hashCode()); } /** * 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session) { log.info(" onOpen session=" + session.getId()); } /** * 连接关闭调用的方法 */ @OnClose public void onClose(Session session) { log.info(session.getId() + ":关闭了"); } /** * 收到客户端发送的字节消息后调用的方法 * * @param message 客户端发送过来的消息 */ @OnMessage public void onBinaryMessage(Session session, byte[] message) { log.info("onMessage session=" + session.getId() + " message =" + message.length); //群发消息 //将流写入文件 saveFileFromBytes(message); //文件写入成功,返回一个ok session.getAsyncRemote().sendText("文件上传ok"); //向客户端写图片 sendFile(session); } public boolean saveFileFromBytes(byte[] b) { //创建文件流对象 FileOutputStream fstream = null; //从map中获取file对象 File file = new File("E://" + this.hashCode() + ".png"); //判断路径是否存在,不存在就创建 if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } try { fstream = new FileOutputStream(file, true); fstream.write(b); } catch (Exception e) { e.printStackTrace(); return false; } finally { if (fstream != null) { try { fstream.close(); } catch (IOException e1) { e1.printStackTrace(); } } } return true; } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息 */ @OnMessage public void onTextMessage(Session session, String message) { log.info("onMessage session=" + session.getId() + " message =" + message); session.getAsyncRemote().sendText("我是服务端:" + message); } private void sendFile(Session session) { byte[] array = null; try { InputStream resourceAsStream = new ClassPathResource("test.png").getInputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int numBytesRead = 0; while ((numBytesRead = resourceAsStream.read(buf)) != -1) { output.write(buf, 0, numBytesRead); } array = output.toByteArray(); output.close(); resourceAsStream.close(); } catch (Exception e) { e.printStackTrace(); } ByteBuffer data = ByteBuffer.wrap(array); session.getAsyncRemote().sendBinary(data); } /** * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("onError"); } }