Java开发之使用websocket实现web客户端与服务器之间的实时通讯

Posted zsq_fengchen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java开发之使用websocket实现web客户端与服务器之间的实时通讯相关的知识,希望对你有一定的参考价值。

使用websocket实现web客户端与服务器之间的实时通讯。以下是个简单的demo。

前端页面

  1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
  4 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
  5 <%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fun"%>
  6 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> 
  7 <c:set var="baseurl" value="${pageContext.request.contextPath}/"></c:set>
  8 
  9 <html>
 10 <head>
 11 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 12 <title>web_socket</title>
 13 
 14 <script type="text/javascript" src="${baseurl}static/js/jquery-2.1.1.js"></script>
 15 <style type="text/css">
 16     .connector {width: 500px;}
 17 </style>
 18 </head>
 19 <body>
 20     Welcome
 21     <br/>
 22     <input id="text" type="text"/>
 23     <button onclick="sendToOne(10008)">发消息给个人</button>
 24     <button onclick="sendToAll(0)">发消息给所有人</button>
 25     <hr/>
 26     <button onclick="closeWebSocket()">关闭WebSocket连接</button>
 27     <hr/>
 28     <div id="message"></div>
 29 </body>
 30 <script type="text/javascript">
 31     var websocket = null;
 32     var host = document.location.host;
 33     
 34     //判断当前浏览器是否支持WebSocket
 35     if (WebSocket in window) {
 36         console.info("浏览器支持Websocket");
 37         websocket = new WebSocket(ws://+host+/${baseurl}/webSocketServer/${userID});
 38     } else {
 39         console.info(当前浏览器 Not support websocket);
 40     }
 41     
 42     //连接发生错误的回调方法
 43     websocket.onerror = function() {
 44         console.info("WebSocket连接发生错误");
 45         setMessageInnerHTML("WebSocket连接发生错误"); 
 46     }
 47     
 48     //连接成功建立的回调方法
 49     websocket.onopen = function() {
 50         console.info("WebSocket连接成功");
 51         setMessageInnerHTML("WebSocket连接成功"); 
 52     } 
 53     
 54     //接收到消息的回调方法 
 55     websocket.onmessage = function(event) {
 56         console.info("接收到消息的回调方法");
 57         console.info("这是后台推送的消息:"+event.data);
 58         setMessageInnerHTML(event.data); 
 59         console.info("webSocket已关闭!");
 60     }
 61     
 62     //连接关闭的回调方法 
 63     websocket.onclose = function() {
 64         setMessageInnerHTML("WebSocket连接关闭");
 65     }
 66     
 67     //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
 68     window.onbeforeunload = function() {
 69         closeWebSocket();
 70     }
 71     
 72     //关闭WebSocket连接 
 73     function closeWebSocket() {
 74         websocket.close();
 75     }
 76     
 77     //将消息显示在网页上
 78     function setMessageInnerHTML(innerHTML) {
 79         document.getElementById(message).innerHTML += innerHTML + <br/>;
 80     }
 81     
 82     //发送消息给其他客户端
 83     function sendToOne(receiverId) {
 84         var messageContent = document.getElementById(text).value;
 85         var message = {};
 86         message.senderId = "${userID}";
 87         message.receiverId = receiverId;
 88         message.messageContent = messageContent;
 89         websocket.send(JSON.stringify(message));
 90     }
 91     
 92     //发送消息给所有人
 93     function sendToAll() {
 94         var messageContent = document.getElementById(text).value;
 95         var message = {};
 96         message.senderId = "${userID}";
 97         message.receiverId = "0";
 98         message.messageContent = messageContent;
 99         websocket.send(JSON.stringify(message));
100     }
101 </script>
102 </html>

后台代码

 1 import java.util.Date;
 2 
 3 public class WebSocketMessage {
 4 
 5     /**
 6      * 发送者ID
 7      */
 8     private String senderId;
 9 
10     /**
11      * 接受者ID, 如果为0, 则发送给所有人
12      */
13     private String receiverId;
14 
15     /**
16      * 会话内容
17      */
18     private String messageContent;
19 
20     /**
21      * 发送时间
22      */
23     private Date sendTime;
24 
25     public String getSenderId() {
26         return senderId;
27     }
28 
29     public void setSenderId(String senderId) {
30         this.senderId = senderId;
31     }
32 
33     public String getReceiverId() {
34         return receiverId;
35     }
36 
37     public void setReceiverId(String receiverId) {
38         this.receiverId = receiverId;
39     }
40 
41     public String getMessageContent() {
42         return messageContent;
43     }
44 
45     public void setMessageContent(String messageContent) {
46         this.messageContent = messageContent;
47     }
48 
49     public Date getSendTime() {
50         return sendTime;
51     }
52 
53     public void setSendTime(Date sendTime) {
54         this.sendTime = sendTime;
55     }
56 
57 }
 1 import javax.servlet.http.HttpServletResponse;
 2 
 3 import org.springframework.stereotype.Controller;
 4 import org.springframework.web.bind.annotation.PathVariable;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.servlet.ModelAndView;
 7 
 8 @Controller
 9 @RequestMapping("webSocket")
10 public class WebSocketController {
11 
12     @RequestMapping(value = "messagePage/{userID}")
13     public ModelAndView messagePage(@PathVariable String userID, HttpServletResponse response) {
14         ModelAndView mav = new ModelAndView();
15         mav.addObject("userID", userID);
16         mav.setViewName("web_socket");
17         return mav;
18     }
19 }
  1 import java.io.IOException;
  2 import java.util.Map;
  3 import java.util.concurrent.ConcurrentHashMap;
  4 
  5 import javax.websocket.OnClose;
  6 import javax.websocket.OnError;
  7 import javax.websocket.OnMessage;
  8 import javax.websocket.OnOpen;
  9 import javax.websocket.Session;
 10 import javax.websocket.server.PathParam;
 11 import javax.websocket.server.ServerEndpoint;
 12 
 13 import com.alibaba.fastjson.JSON;
 14 import com.utime.facade.model.systemplate.WebSocketMessage;
 15 
 16 @ServerEndpoint("/webSocketServer/{userID}")
 17 public class WebSocketServer {
 18     // 连接客户端数量
 19     private static int onlineCount = 0;
 20     // 所有的连接客户端
 21     private static Map<String, WebSocketServer> clients = new ConcurrentHashMap<String, WebSocketServer>();
 22     // 当前客户端连接的唯一标示
 23     private Session session;
 24     // 当前客户端连接的用户ID
 25     private String userID;
 26 
 27     /**
 28      * 客户端连接服务端回调函数
 29      * 
 30      * @param userID 用户ID
 31      * @param session 会话
 32      * @throws IOException
 33      */
 34     @OnOpen
 35     public void onOpen(@PathParam("userID") String userID, Session session) throws IOException {
 36         this.userID = userID;
 37         this.session = session;
 38 
 39         addOnlineCount();
 40         clients.put(userID, this);
 41         System.out.println("WebSocket日志: 有新连接加入!当前在线人数为" + getOnlineCount());
 42     }
 43 
 44     @OnClose
 45     public void onClose() throws IOException {
 46         clients.remove(userID);
 47         subOnlineCount();
 48         System.out.println("WebSocket日志: 有一连接关闭!当前在线人数为" + getOnlineCount());
 49     }
 50 
 51     /**
 52      * 接受到来自客户端的消息
 53      * 
 54      * @param message
 55      * @throws IOException
 56      */
 57     @OnMessage
 58     public void onMessage(String message) throws IOException {
 59         System.out.println("WebSocket日志: 来自客户端的消息:" + message);
 60         WebSocketMessage webSocketMessage = JSON.parseObject(message, WebSocketMessage.class);
 61 
 62         // 发送消息给所有客户端
 63         if ("0".equals(webSocketMessage.getReceiverId())) {
 64             for (WebSocketServer item : clients.values()) {
 65                 item.session.getAsyncRemote().sendText(webSocketMessage.getMessageContent());
 66                 System.out.println("WebSocket日志: ID为"+ webSocketMessage.getSenderId() +"的用户给ID为"+ item.userID +"的客户端发送:" + webSocketMessage.getMessageContent());
 67             }
 68         } else {    // 发送消息给指定ID的客户端
 69             for (WebSocketServer item : clients.values()) {
 70                 if (item.userID.equals(webSocketMessage.getReceiverId())){
 71                     // 发消息给指定客户端
 72                     item.session.getAsyncRemote().sendText(webSocketMessage.getMessageContent());
 73                     System.out.println("WebSocket日志: ID为"+ webSocketMessage.getSenderId() +"的用户给ID为"+ item.userID +"的客户端发送:" + webSocketMessage.getMessageContent());
 74                     if (!webSocketMessage.getSenderId().equals(webSocketMessage.getReceiverId())) {
 75                         // 发消息给自己
 76                         this.session.getAsyncRemote().sendText(webSocketMessage.getMessageContent());
 77                         System.out.println("WebSocket日志: ID为"+ webSocketMessage.getSenderId() +"的用户给ID为"+ this.userID +"的客户端发送:" + webSocketMessage.getMessageContent());
 78                     }
 79                     break;
 80                 }
 81             }
 82         }
 83     }
 84     
 85     /**
 86      * 服务端报错了
 87      * 
 88      * @param session
 89      * @param error
 90      */
 91     @OnError
 92     public void onError(Session session, Throwable error) {
 93         System.out.println("WebSocket日志: 发生错误");
 94         error.printStackTrace();
 95     }
 96     
 97     /**
 98      * 客户端连接数+1
 99      */
100     public static synchronized void addOnlineCount() {
101         WebSocketServer.onlineCount++;
102     }
103     
104     /**
105      * 客户端连接数-1
106      */
107     public static synchronized void subOnlineCount() {
108         WebSocketServer.onlineCount--;
109     }
110 
111     public static synchronized int getOnlineCount() {
112         return onlineCount;
113     }
114 
115     public static synchronized Map<String, WebSocketServer> getClients() {
116         return clients;
117     }
118 }

写这个的目的只是为了自己做个记录。

以上是关于Java开发之使用websocket实现web客户端与服务器之间的实时通讯的主要内容,如果未能解决你的问题,请参考以下文章

即时通讯开发中WebSocket和SSE技术如何实现Web端消息推送

Java web 服务端消息推送用啥比较好

Netty框架之协议应用一(redis客户端简单实现以及使用websocket实现弹幕功能)

Netty框架之协议应用一(redis客户端简单实现以及使用websocket实现弹幕功能)

Netty框架之协议应用一(redis客户端简单实现以及使用websocket实现弹幕功能)

Websocket 和跨域