首页 » 软件开发 » java websocket实现点对点即时聊天(连接点对点方法关闭消息)

java websocket实现点对点即时聊天(连接点对点方法关闭消息)

雨夜梧桐 2024-07-24 10:39:45 0

扫一扫用手机浏览

文章目录 [+]

必要环境:JDK1.7以上,tomcat7.0以上。
以下是干货:

1、websocket的jar直接从tomcat运行库里面添加到build path里面。

2、前台聊天页面,通过ws://localhost:8080/newProject/websocketTest与后台建立连接

java websocket实现点对点即时聊天(连接点对点方法关闭消息) 软件开发
(图片来自网络侵删)

<%@ page language=\"java\" import=\"java.util.\" pageEncoding=\"UTF-8\"%> <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"><html><head> <title>My JSP 'socketChart.jsp' starting page</title><script type=\"text/javascript\" src=\"js/jquery-1.8.2.js\"></script></head> <body>${username}<br/>在线人数:<div id=\"onlineCount\">0</div><br />发送对象:<input id=\"username\" type=\"text\" width=\"50px\"/>内容:<input id=\"text\" type=\"text\" /><button onclick=\"send()\">发送消息</button><hr /><button onclick=\"closeWebSocket()\">关闭WebSocket连接</button><hr /><div id=\"message\"></div></body><script type=\"text/javascript\">var websocket = null;//判断当前浏览器是否支持WebSocketif ('WebSocket' in window) {websocket = new WebSocket(\"ws://localhost:8080/newProject/websocketTest\");} else {alert('当前浏览器 Not support websocket')}//连接发生错误的回调方法websocket.onerror = function() {setMessageInnerHTML(\"WebSocket连接发生错误\");};//连接成功建立的回调方法websocket.onopen = function() {setMessageInnerHTML(\"WebSocket连接成功\");}//接收到消息的回调方法websocket.onmessage = function(event) {debuggervar messageJson=eval(\"(\"+event.data+\")\");if(messageJson.messageType==\"message\"){setMessageInnerHTML(messageJson.data);}if(messageJson.messageType==\"onlineCount\"){document.getElementById('onlineCount').innerHTML=messageJson.data;}}//连接关闭的回调方法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();}//发送消息function send() {var message = document.getElementById('text').value;var username = document.getElementById('username').value;websocket.send(username+\"@\"+message);document.getElementById('message').innerHTML += message + '<br/>';}</script></html>

3、登录页面,简单的创建一个session会话模拟用户登录用作点对点聊天的唯一标识。

<%@ page language=\"java\" import=\"java.util.\" pageEncoding=\"UTF-8\"%><%String path = request.getContextPath();String basePath = request.getScheme() + \"://\"+ request.getServerName() + \":\" + request.getServerPort()+ path + \"/\";%> <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"><html><head><base href=\"<%=basePath%>\"> <title>My JSP 'login.jsp' starting page</title> </head> <body><center><form action=\"chatWebsocket/login.do\" method=\"post\"><table><tr><td>username:</td><td><input type=\"text\" id=\"username\" name=\"username\"/></td></tr><tr><td colspan=\"2\"> <input type=\"submit\" value=\"登录\"/></td></tr></table></form></center></body></html>

4、controller类,模拟登录创建会话,并向socket工具类里面传送登录用户的唯一标识。

package com.test.controller; import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping; import com.test.socket.WebSocketTest; @Controller@RequestMapping(\"chatWebsocket\")public class ChartWebsocketController {@RequestMapping(\"login\")public void login(String username,HttpServletRequest request,HttpServletResponse response) throws Exception{HttpSession session=request.getSession();session.setAttribute(\"username\", username);WebSocketTest.setHttpSession(session);request.getRequestDispatcher(\"/socketChart.jsp\").forward(request, response);}@RequestMapping(\"loginOut\")public void loginOut(HttpServletRequest request,HttpServletResponse response) throws Exception{HttpSession session=request.getSession();session.removeAttribute(\"username\");request.getRequestDispatcher(\"/socketChart.jsp\").forward(request, response);}}

5、socket消息处理类,负责消息的接收与转发,作用类似于TCP的服务端,@ServerEndpoint(\"/websocketTest\")的作用是声明websocket的连接路径。

package com.test.socket; import java.io.IOException;import java.util.HashMap;import java.util.Map;import java.util.Map.Entry; import javax.servlet.http.HttpSession;import javax.websocket.OnClose;import javax.websocket.OnError;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.Session;import javax.websocket.server.ServerEndpoint;import com.google.gson.Gson; / @ServerEndpoint /@ServerEndpoint(\"/websocketTest\")public class WebSocketTest {private static int onlineCount = 0;//存放所有登录用户的Map集合,键:每个用户的唯一标识(用户名)private static Map<String,WebSocketTest> webSocketMap = new HashMap<String,WebSocketTest>();//session作为用户简历连接的唯一会话,可以用来区别每个用户private Session session;//httpsession用以在建立连接的时候获取登录用户的唯一标识(登录名),获取到之后以键值对的方式存在Map对象里面private static HttpSession httpSession;public static void setHttpSession(HttpSession httpSession){WebSocketTest.httpSession=httpSession;}/ 连接建立成功调用的方法 @param session 可选的参数。
session为与某个客户端的连接会话,需要通过它来给客户端发送数据 /@OnOpenpublic void onOpen(Session session) {Gson gson=new Gson();this.session = session;webSocketMap.put((String) httpSession.getAttribute(\"username\"), this);addOnlineCount(); // MessageDto md=new MessageDto();md.setMessageType(\"onlineCount\");md.setData(onlineCount+\"\");sendOnlineCount(gson.toJson(md));System.out.println(getOnlineCount());}/ 向所有在线用户发送在线人数 @param message /public void sendOnlineCount(String message){for (Entry<String,WebSocketTest> entry : webSocketMap.entrySet()) {try {entry.getValue().sendMessage(message);} catch (IOException e) {continue;}}}/ 连接关闭调用的方法 /@OnClosepublic void onClose() {for (Entry<String,WebSocketTest> entry : webSocketMap.entrySet()) {if(entry.getValue().session==this.session){webSocketMap.remove(entry.getKey());break;}}//webSocketMap.remove(httpSession.getAttribute(\"username\"));subOnlineCount(); // System.out.println(getOnlineCount());} / 服务器接收到客户端消息时调用的方法,(通过“@”截取接收用户的用户名) @param message 客户端发送过来的消息 @param session 数据源客户端的session /@OnMessagepublic void onMessage(String message, Session session) {Gson gson=new Gson();System.out.println(\"收到客户端的消息:\" + message);StringBuffer messageStr=new StringBuffer(message);if(messageStr.indexOf(\"@\")!=-1){String targetname=messageStr.substring(0, messageStr.indexOf(\"@\"));String sourcename=\"\";for (Entry<String,WebSocketTest> entry : webSocketMap.entrySet()) {//根据接收用户名遍历出接收对象if(targetname.equals(entry.getKey())){try {for (Entry<String,WebSocketTest> entry1 : webSocketMap.entrySet()) {//session在这里作为客户端向服务器发送信息的会话,用来遍历出信息来源if(entry1.getValue().session==session){sourcename=entry1.getKey();}}MessageDto md=new MessageDto();md.setMessageType(\"message\");md.setData(sourcename+\":\"+message.substring(messageStr.indexOf(\"@\")+1));entry.getValue().sendMessage(gson.toJson(md));} catch (IOException e) {e.printStackTrace();continue;}}}}} / 发生错误时调用 @param session @param error /@OnErrorpublic void onError(Session session, Throwable error) {error.printStackTrace();} / 这个方法与上面几个方法不一样。
没有用注解,是根据自己需要添加的方法。
@param message @throws IOException /public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);// this.session.getAsyncRemote().sendText(message);} public static synchronized int getOnlineCount() {return onlineCount;} public static synchronized void addOnlineCount() {WebSocketTest.onlineCount++;} public static synchronized void subOnlineCount() {WebSocketTest.onlineCount--;}}

6、消息封装的数据传输对象

package com.chart.dto; public class MessageDto {private String messageType;private String data;public String getMessageType() {return messageType;}public void setMessageType(String messageType) {this.messageType = messageType;}public String getData() {return data;}public void setData(String data) {this.data = data;}}

相关文章

语言中的借用,文化交融的桥梁

自古以来,人类社会的交流与发展离不开语言的传播。在漫长的历史长河中,各民族、各地区之间的文化相互碰撞、交融,产生了许多独特的语言现...

软件开发 2025-01-01 阅读1 评论0

机顶盒协议,守护数字生活的新卫士

随着科技的飞速发展,数字家庭逐渐走进千家万户。在这个时代,机顶盒成为了连接我们与丰富多彩的数字世界的重要桥梁。而机顶盒协议,作为保...

软件开发 2025-01-01 阅读1 评论0

语言基础在现代社会的重要性及方法步骤

语言是人类沟通的桥梁,是社会发展的基础。语言基础作为语言学习的基石,对于个人、社会乃至国家的发展具有重要意义。本文将从语言基础在现...

软件开发 2025-01-01 阅读2 评论0

粤语电影,传承文化,点亮时代之光

粤语电影,作为中国电影产业的一朵奇葩,以其独特的地域特色、丰富的文化内涵和鲜明的艺术风格,赢得了广大观众的喜爱。本文将从粤语电影的...

软件开发 2025-01-01 阅读3 评论0

苹果游戏语言,塑造未来娱乐体验的基石

随着科技的飞速发展,游戏产业逐渐成为全球娱乐市场的重要支柱。在我国,游戏产业更是蓬勃发展,吸引了无数玩家和投资者的目光。而在这其中...

软件开发 2025-01-01 阅读1 评论0