B/S中一般通信和WebSocket的区别:
在B/S结构的应用中,传统的通信机制是请求-响应的模式,也就是说只有客户端发送请求,服务端才会给出相应的响应(不考虑程序问题或者是其他原因),服务器不能够主动的为浏览器推送消息。但是WebSocket可以实现客户端和服务端的双向通信,其原理就是在客户端和服务器端建立一个通信的管道,来实现客户端和服务器端的双向通信。
通过在写例子的过程中,我的理解是(Java为例-注解方式):服务器端通过注解为方法注册监听事件(项目启动会自动扫描这些注解然后进行装载配置),然后客户端通过绑定到WebSocket对象上的方法共同实现客户端和服务器端的消息传输(简单理解)。
①服务端配置
1 package com.chat.config; 2 ?3 import java.util.Set; 4 import javax.websocket.Endpoint; 5 import javax.websocket.server.ServerApplicationConfig; 6 import javax.websocket.server.ServerEndpointConfig; 7 ?8 public class WebSocketConfig implements ServerApplicationConfig{ 9 10 ????/**11 ?????* 基于注解的开启方式12 ?????*/13 ????@Override14 ????public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanedSockets) {15 ????????System.out.println("=========================");16 ????????System.out.println(" ?WebSocket装载配置...");17 ????????System.out.println("=========================");18 ????????return scanedSockets;19 ????}20 21 ????/**22 ?????* 结余接口的开启方式23 ?????*/24 ????@Override25 ????public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {26 ????????return null;27 ????}28 29 }
②服务端Socket
?1 package com.chat.socket; ?2 ??3 import java.io.IOException; ?4 import java.io.UnsupportedEncodingException; ?5 import java.net.URLDecoder; ?6 import java.util.ArrayList; ?7 import java.util.Iterator; ?8 import java.util.List; ?9 ?10 import javax.websocket.OnClose; 11 import javax.websocket.OnMessage; 12 import javax.websocket.OnOpen; 13 import javax.websocket.Session; 14 import javax.websocket.server.ServerEndpoint; 15 ?16 import com.chat.message.Message; 17 ?18 @ServerEndpoint("/chat") 19 public class ChatSocket { 20 ?????21 ????private static List<String> names = new ArrayList<String>(); 22 ????private static List<Session> sessions = new ArrayList<Session>(); 23 ????//当前登录用户 24 ????private static String userName ; 25 ?26 ????/** 27 ?????* 每一个通信管道对应一个Socket实例,也是一个Session 28 ?????*/ 29 ????public ChatSocket () { 30 ????????System.out.println("ChatSocket 创建完成."); 31 ????} 32 ?????33 ????/** 34 ?????* 会话开启事件 35 ?????* @param session 36 ?????*/ 37 ????@OnOpen 38 ????public void chatOpen (Session session) { 39 ????????this.userName = session.getQueryString(); 40 ????????try { 41 ????????????userName = URLDecoder.decode(userName, "utf-8"); 42 ????????????if (null != userName && !userName.isEmpty()) { 43 ????????????????userName = userName.split("=")[1].trim(); 44 ????????????????String msgStr = "欢迎" + userName + "加入聊天室!"; 45 ????????????????names.add(userName);//用户列表 46 ????????????????Message msg = new Message(); 47 ????????????????msg.setNames(names); 48 ????????????????msg.setMsg(msgStr); 49 ????????????????sessions.add(session); 50 ????????????????broadcast(msg); 51 ????????????} 52 ????????} catch (Exception e) { 53 ????????????e.printStackTrace(); 54 ????????} 55 ????} 56 ?????57 ????/** 58 ?????* 处理客户端发送的消息并响应 59 ?????* @param session 60 ?????* @param msg 客户端发送的消息体 61 ?????*/ 62 ????@OnMessage 63 ????public void ChatMsg (Session session,String msg) { 64 ????????String msgBody = "【" + this.userName + "】说:</br>" + msg; 65 ????????Message msgObj = new Message(); 66 ????????msgObj.setMsg(msgBody); ?67 ????????msgObj.setNames(names); 68 ????????//广播客户端消息给每个登录用户 69 ????????this.broadcast(msgObj); 70 ????} 71 ?????72 ????/** 73 ?????* 会话关闭事件 74 ?????*/ 75 ????@OnClose 76 ????public void close (Session session) { 77 ????????String msg = "欢送 " + this.userName + " 离开聊天室!"; 78 ????????//移除当前推出的会话(管道) 79 ????????sessions.remove(session); 80 ????????Message msgObj = new Message(); 81 ????????names.remove(this.userName); 82 ????????msgObj.setMsg(msg); 83 ????????msgObj.setNames(names); 84 ????????this.broadcast(msgObj); 85 ????} 86 ?????87 ????/** 88 ?????* 消息广播的方法 89 ?????* @param msg 90 ?????*/ 91 ????public void broadcast(Message msg) { 92 ????????for (Iterator<Session> sessionIt = sessions.iterator();sessionIt.hasNext();) { 93 ????????????try { 94 ????????????????sessionIt.next().getBasicRemote().sendText(msg.toJson()); 95 ????????????????System.out.println(msg.toJson()); 96 ????????????} catch (IOException e) { 97 ????????????????e.printStackTrace(); 98 ????????????} 99 ????????}100 ????}101 }
③格式化消息体
1 package com.chat.message; 2 ?3 import java.util.List; 4 ?5 import com.google.gson.Gson; 6 ?7 public class Message { 8 ?9 ????private List<String> names;10 ????private String msg;11 ????12 ????private static Gson gson = new Gson();13 ????14 ????public List<String> getNames() {15 ????????return names;16 ????}17 ????public void setNames(List<String> names) {18 ????????this.names = names;19 ????}20 ????public String getMsg() {21 ????????return msg;22 ????}23 ????public void setMsg(String msg) {24 ????????this.msg = msg;25 ????}26 ????27 ????public String toJson () {28 ????????return gson.toJson(this);29 ????}30 ????31 }
④应用-登录
1 package com.chat.servlet; 2 ?3 import java.io.IOException; 4 import java.io.PrintWriter; 5 ?6 import javax.servlet.ServletException; 7 import javax.servlet.annotation.WebServlet; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 import javax.servlet.http.HttpSession;12 13 14 @WebServlet("/loginServlet")15 public class LoginServlet extends HttpServlet {16 ????private static final long serialVersionUID = 1L;17 18 ????protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {19 ????????this.doPost(request, response);20 ????}21 22 ????protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {23 ????????String userName = null == request.getParameter("userName") ? "" : request.getParameter("userName").trim();24 ????????HttpSession session = ?request.getSession();25 ????????if (!userName.isEmpty()) {26 ????????????session.setAttribute("userName", userName);27 ????????}28 ????????response.sendRedirect("jsp/chat.jsp");29 ????}30 }
⑤客户端-登录页面
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 ????pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Login Page</title> 8 </head> 9 <body>10 11 <form action="${pageContext.request.contextPath}/loginServlet" method="get">12 ????UserName:<input type="text" name="userName"/>13 ????<br/>14 ????<input type="submit" value="Submit"/>15 </form>16 </body>17 </html>
⑥客户端-聊天页面
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 ????pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Chat Page</title> 8 <script type="text/javascript" src="${pageContext.request.contextPath}/plugins/jquery-1.8.3.min.js"></script> 9 <script type="text/javascript">10 ????//声明全局变量11 ????var ws;12 ????var userName = ‘${sessionScope.userName}‘;13 ????var target = "ws://localhost:9999/ChatDemo/chat?userName=" + userName;14 ????$(function () {15 ????????//打开页面就开启Socket连接16 ????????if (‘WebSocket‘ in window) {17 ????????????ws = new WebSocket(target);18 ????????} else if (‘MozWebSocket‘ in window) {//火狐19 ????????????ws = new MozWebSocket(target);20 ????????} else {21 ????????????return alert("请使用支持WebSocket的浏览器!");22 ????????}23 ????????ws.onmessage = function (event) {24 ????????????if (event) {25 ????????????????console.dir(event);26 ????????????????$("#userList").html("");27 ????????????????eval("var data = " + event.data + ";");28 ????????????????$(data.names).each(function () {29 ????????????????????$("#userList").append(this + "</br>");30 ????????????????});31 ????????????????$("#chatContent").append(data.msg + "<br/>");32 ????????????} ???33 ????????}34 ????????//为send按钮增加点击事件(发送消息按钮)35 ????????$("#sendBtn").on("click",function () {36 ????????????//获取需要发送的消息体37 ????????????var msgEdit = $("input[name=‘sendMsg‘]").val();38 ????????????ws.send(msgEdit);39 ????????????$("input[name=‘sendMsg‘]").val("");40 ????????});41 ????});42 </script>43 <style type="text/css">44 ????45 </style>46 </head>47 <body>48 ????<div id="chatContent" style="float:left;width:267px;height:240px;border:1px solid black;">49 ????</div>50 ????51 ????<div id="userList" style="float:left;width:112px;height:240px;border:1px solid black;">52 ????</div>53 ????<div id="msgSendContent" style="clear: both;">54 ????????<input type="text" name="sendMsg" /><button id="sendBtn">Send</button>55 ????</div>56 </body>57 </html>
例子结构(非Maven)
WebSocket 实现群聊 - 简单测试例子
原文地址:https://www.cnblogs.com/simpleJokerKing/p/8849059.html