websocket实现简单的消息发送
websocket:
效果图
前端代码
html部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | <div> <!-- <div style= "float: left;height: 100vh;width: 1%" ></div>--> <div style= "float: left;width: 20%;height: 96vh;border-radius: 0.5rem;" > <div class = "el-dropdown-link" style= "margin-left: 1.6vh;margin-top: 0.7vw;margin-bottom: 0.7vw" >返回</div> <div class = "info" style= "height: 9vh;width: 100%;text-align: center;border-radius: 10px;" > <div style= "width: 95%;height: 8vh;border-radius: 0.5rem;margin-left: 3vw;" > <div style= "float: left" > <img style= "border-radius: 50%;height: 7vh;width: 3.5vw;margin-left: 1rem;margin-right: 0.7rem;margin-top: 1vh;" src= "https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp" > </div> <div style= "float: left;margin-top: 2vh;font-size: 2.5vh" > {{ userName }} </div> </div> </div> <hr/> <div style= "height: 4vh;width: 100%;text-align: center" > <div style= "margin-top: 2vh;font-weight: bold;font-size: 2.5vh" >消息列表</div> </div> <hr/> <div v- for = "(name,index) in userList" :key= "name.id" > <div :id= "'id'+name.id" class = "messagediv" style= "width: 95%;height: 7.7vh;border-radius: 0.5rem;" tabindex= "2" @click = "getStyMessage(name)" > <div style= "float: left" > <img style= "border-radius: 50%;height: 6.3vh;width: 3vw;margin-left: 1rem;margin-right: 0.7rem;margin-top: 5px;" src= "https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp" > </div> <div style= "float: left;margin-top: 2vh;font-size: 2.5vh" > {{ name.sender }} </div> </div> <div style= "width: 19.5vw" > <hr v- if = "index!=list.length-1" style= "font-size: 0.001rem;margin-left: 9vh;color: gray;width: 70%;top: -10px" /> </div> </div> </div> <div style= "float: left;height: 96vh;width: 0.5%" ></div> <div style= "float: left;width: 78%;background-color: rgb(250,250,249);height: 96vh;" > <div style="width: 100 %;height: 3rem; float : left; text-align: center;background-color: #f0f0f0;border-radius: 0 .5rem;"> <div style= "margin-top: 0.8rem;font-size: 2.5vh" >{{name}}</div> </div> <div style= "float: left;clear: left;width: 100%;margin-top: 0.8rem;height: 80vh;overflow: auto" > <div v- for = "message in list" :key= "message.id" > <div style= "text-align: center;width: 100%;font-size: 1.6vh;" >{{ message.date }}</div> <div v- if = "message.sender!=userName" style= "width: 100%;height: 3rem" > <div style= "float: left" > <img style= "border-radius: 50%;height: 6.3vh;width: 3vw;margin-left: 4rem;margin-right: 0.7rem" src= "https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp" > </div> <div> <!-- <div style= "margin-left: 0.7rem;font-size: 0.5rem" >nih</div>--> <div style= "float: left;background-color: white;height: 4.6vh;;border-radius: 10px;margin-top: 0.9vh" > <div style= "margin-left: 0.8vw;margin-right: 0.8vw;margin-top:0.68vh;font-size: 2.5vh" >{{message.message}}</div> </div> </div> </div> <div v- if = "message.sender==userName" style= "width: 100%;height: 3rem" > <div style= "float: right" > <img style= "border-radius: 50%;height: 6.3vh;width: 3vw;margin-right: 4rem;margin-left: 0.7rem" src= "https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp" > </div> <div> <!-- <div style= "margin-left: 0.7rem;font-size: 0.5rem" >nih</div>--> <div style= "float: right;background-color: cornflowerblue;height: 4.6vh;border-radius: 10px;margin-top: 0.4rem;" > <div style= "margin: 0.27rem;margin-left: 0.7rem;margin-right: 0.7rem;font-size: 2.5vh" >{{message.message}}</div> <!-- <div style= "font-size: 1.8vh;margin-left: 0.5rem;color: gray;margin-top: 0.2rem" >--> <!-- <span v- if = "true" >已读</span>--> <!-- <span v- if = "false" >未读</span>--> <!-- </div>--> </div> </div> </div> </div> <div style= "width: 100%;height: 4vh" ></div> </div> <div v- if = "name!=''" style= "clear: left;position:absolute;bottom: 10px;width: 100%;height: 5vh;background-color: white" > <input v-model= "message" type= "text" name= "message" style= "float: left;width: 55%;margin-left: 7vw;height: 4.7vh;border-radius: 0.5rem;" > <div style= "float: left" > <input @click = "addMessage" value= "发送" type= "button" style="height: 5vh;width: 5vw;border-radius: 0 .5rem;margin-left: 0 .7vw; font-size: 2 .5vh;margin-top: 0 .1vh;"/> </div> </div> </div> </div> |
js部分
1 | mounted部分:页面加载就连接,然后就实时接收消息 |
1 2 3 4 5 6 7 8 9 10 | mounted() { var socket = new WebSocket( "ws://localhost:8818/ws/2" ); console.log( this ) const data = this ; socket.onmessage = function (event) { data.setMessage( name, event.data ) console.log( "收到服务器消息: " + event.data); console.log(data); }; }, |
方法部分
1 2 3 4 5 6 7 | // 接收消息 setMessage(name,message){ console.log( this .list) //date: "2023-10-26T14:06:06.387", read: 0, sender: "李四", name: "张三", id: 1, message: "你好2 this .list.push({date: new Date(),read: 0,sender: this .userName,name: name,id: this .list.length+1, message: message }) this .getMessages(); }, |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // 发送消息 addMessage(){ var i =1; console.log( this .list) const message = this .message; if (message!= null &&message!= '' ){ this .$http.post( '/api/cloud-member/member/webSocket' ,{ 'id' : this .id, 'message' :message, 'name' : this .name,sender: this .userName }).then(response => { console.log(response); if (i<=1){ // 请求成功处理 this .getMessages(); const date = new Date(); console.log( new Date()); console.log( this .date); if (date.getTime()- this .date>=300000){ var month = date.getMonth() + 1 const year = date.getFullYear()+ "-" +month+ "-" +date.getDate()+ " " +date.getHours()+ ":" +date.getMinutes(); this .list.push({date: year, read: 0,sender: this .userName, name: this .name, id: this .list.length+1, message: message}); } else { this .list.push({date: '' , read: 0,sender: this .userName, name: this .name, id: this .list.length+1, message: message}); } // this.getMessage({name: this.userName,sender: this.name}) i++; } }). catch (error => { // 请求失败处理 console.log(error); }); } this .message = '' ; }, |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | getMessage(name){ // console.log(name); // this.getMessages(); this .name = name.sender this .list = []; }, // 修改时间 getDateTime(name){ this .lists.forEach(list=>{ if ((list.sender==name.sender&&list.name==name.name)||(list.sender==name.name&&list.name==name.sender)){ // 5分钟 300000 let date = new Date(list.date).getTime(); console.log(date) if (date- this .date>300000){ this .date = date; list.date = list.date.substring(0,16).replace( 'T' , ' ' ); // if (id==1){ // //date: "2023-10-26T14:06:06.387", read: 0, sender: "李四", name: "张三", id: 1, message: "你好2 // this.list.push({date: item.date,read: item.read,sender: this.userName,name: this.name,id: this.list.length+1, message: item.message,}) // } } else { list.date = '' ; } //date: "2023-10-26T14:06:06.387", read: 0, sender: "李四", name: "张三", id: 1, message: "你好2 this .list.push({date: list.date, read: 0,sender: list.sender, name: list.name, id: this .list.length+1, message: list.message}); console.log( this .list) } }) }, getStyMessage(name){ // console.log(name); this .getMessages(); this .name = name.sender this .list = []; this .getStyle(name.id) this .getDateTime(name); },<br> // 消息列表选中变颜色 getStyle(id){ let classNames = document.getElementsByClassName( "messagediv" ); for ( let i = 0; i < classNames.length; i++) { classNames[i].style.backgroundColor = "white" } const ids = document.getElementById( "id" +id); ids.style.backgroundColor = "#e1e1e1" ; }, getMessages(){ this .$http.get( '/api/cloud-member/member/getMessage/' + this .userName).then(response => { // console.log(Array.from(response.data.data)); const m = response.data.data; if (Array.from(m).length>0){ const list = Array.from(response.data.data); this .lists = list; } this .userList = []; const set = new Set(); this .lists.forEach(item=>{ // 必须要跟我聊过天的才显示 过滤掉自己 if (item.sender== this .userName||item.name== this .userName){ if (item.sender!= this .userName){ set.add(item.sender) } } }) const name = Array.from(set) for ( let i = 0; i < name.length; i++) { this .userList.push({id: i+1,sender: name[i],name: this .userName}); } }). catch (error => { // 请求失败处理 console.log(error); }); } |
后端java代码
websocket类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /** * WebSocket服务 */ @Component @ServerEndpoint( "/ws/{sid}" ) public class WebSocketServer { //存放会话对象 private static Map<String, Session> sessionMap = new HashMap(); private Map<String, Object> map = new HashMap(); private List<String> list = new ArrayList<>(); /** * 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam( "sid" ) String sid) { System.out.println( "客户端:" + sid + "建立连接" ); list.add(session.getId()); sessionMap.put(sid, session); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息 */ @OnMessage public void onMessage(String message, @PathParam( "sid" ) String sid) { map.put(sid,(map.get(sid)== null ? "" :(map.get(sid)+ "," ))+message); System.out.println( "收到来自客户端:" + sid + "的信息:" + map); } /** * 连接关闭调用的方法 * * @param sid */ @OnClose public void onClose(@PathParam( "sid" ) String sid) { System.out.println( "连接断开:" + sid); sessionMap.remove(sid); } /** * 群发 * * @param message */ public void sendToAllClients(String message) { Collection<Session> sessions = sessionMap.values(); for (Session session : sessions) { try { //服务器向客户端发送消息 session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } /** * 私发 * * @param message */ public void sendToAllClient(String id,String message) { Session session = sessionMap.get(id); if (session != null ) { try { // 向客户发送消息 session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } else { System.out.println( "找不到该客户的会话信息" ); } } } |
websocket配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * @Author: xhj * @Date: 2023/10/23/20:15 * @Description: */ /** * WebSocket配置类,用于注册WebSocket的Bean */ @Configuration public class WebSocketConfiguration { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } } |
发送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @PostMapping ( "/webSocket" ) public R webSocket( @RequestBody Map<String,Object> objectMap){ // Map<String, Object> map = new HashMap<>(); // map.put("id",objectMap.get("id")); // map.put("message",objectMap.); // map.put("sender",sender); // map.put("name",name); objectMap.put( "date" , LocalDateTime.now()); objectMap.put( "read" , 0 ); //基于WebSocket实现发送消息 webSocketServer.sendToAllClient(objectMap.get( "id" )+ "" , objectMap.get( "message" )+ "" ); objectMap.put( "id" ,list.size()+ 1 ); list.add(objectMap); return R.ok(list); } |
获取消息
1 2 3 4 5 6 7 8 9 10 11 | @GetMapping ( "/getMessage/{sender}" ) public R getMessage( @PathVariable ( "sender" ) String sender){ List<Map<String,Object>> list1 = new ArrayList<>(); for (Map<String, Object> map : list) { if (map.get( "sender" ).equals(sender)||map.get( "name" ).equals(sender)){ list1.add(map); } } System.out.println(list1); return R.ok(list1); } |
因为没有对接数据库所以我就使用了map来放数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | private List<Map<String,Object>> list = new ArrayList<>(); public MemberController(){ HashMap<String, Object> map = new HashMap<>(); map.put( "id" , this .list.size()+ 1 ); map.put( "message" , "你好2" ); map.put( "sender" , "李四" ); map.put( "name" , "张三" ); map.put( "date" , LocalDateTime.now()); map.put( "read" , 0 ); HashMap<String, Object> map2 = new HashMap<>(); map2.put( "id" , this .list.size()+ 1 ); map2.put( "message" , "你好2" ); map2.put( "sender" , "张三" ); map2.put( "name" , "李四" ); map2.put( "date" , LocalDateTime.now()); map2.put( "read" , 0 ); HashMap<String, Object> map3 = new HashMap<>(); map3.put( "id" , this .list.size()+ 1 ); map3.put( "message" , "你好2" ); map3.put( "sender" , "张三" ); map3.put( "name" , "王五" ); map3.put( "date" , LocalDateTime.now()); map3.put( "read" , 0 ); list.add(map); list.add(map2); list.add(map3); } |
现在能简单的通讯了,最重要的是理解,有可能放入你的电脑执行会有bug
如果你对接数据库,前端就不需要写这么麻烦了
后续我对此进行了优化和对接数据库,最重要的就是websocket类里面的几个方法,最后我前端写了个websocket.js,全局使用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端