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端消息推送
Netty框架之协议应用一(redis客户端简单实现以及使用websocket实现弹幕功能)
Netty框架之协议应用一(redis客户端简单实现以及使用websocket实现弹幕功能)