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 }

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

原文地址:https://www.cnblogs.com/zhaosq/p/11804154.html

时间: 2024-10-21 08:39:44

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

WEB客户端和服务器

# encoding=utf-8 #python 2.7.10 #xiaodeng #HTTP权威指南 #HTTP协议:超文本传输协议是在万维网上进行通信时所使用的协议方案. #WEB客户端和服务器: #HTTP权威指南 5页 #最常见的客户端就是web浏览器.web浏览器向服务器请求HTTP对象,并将这些对象显示在你的屏幕上. #1)浏览一个页面时,浏览器会向服务器www.oreilly.com发送一条http请求. #2)服务器会去寻找所期望的对象(index.html),如果成功,就将对象

Web客户端和服务器交互过程和模型

客户端/服务器(client/server)这个术语可追溯到上个千年(20世纪80年代),表示通过网络连接起来的个人计算机.客户端/服务器也可用于描述两个计算机程序的关系--客户程序和服务器程序.客户向服务器请求某种服务(比如请求一个文件或数据库访问),服务器满足请求并通过网络将结果传送给客户端.虽然客户端和服务器程序可存在于同一台计算机中,但它们通常都运行在不同计算机上.一台服务器处理多个客户端请求也是很常见的. 最常见的Web客户端就是浏览器了,一次请求/响应的模型如下图所示: 这里需要说明

用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰

服务器: 1.与客户端的交流手段多是I/O流的方式 2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接 3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输入流,同时所有客户端的所有输出流都会包含在服务器的输入流中. (即套接字即使建立连接,输入输出流都是相对自己的而言的,向外发送自己的内部的信息都用输出流,接受外部的数据都使用输入流!) 简单服务器的代码实现: public static void main(String [] args){ try

Android:客户端和服务器之间传输数据加密

Android客户端与服务器进行数据传输时,一般会涉及到两类数据的加密情况,一类是只有创建者才能知道的数据,比如密码:另一类是其他比较重要的,但是可以逆向解密的数据. 第一类:密码类的数据,为了让用户放心注册,密码类的数据的加密一般都是经过双重加密的,第一重加密使用不可逆的MD5算法加密,第二重加密是可逆的加密,常见的可逆加密有对称加密和非对称加密.上述不可逆的意思就是一旦加密就不能反向得到密码原文,一般用来加密用户密码,app的服务器端一般存储的也都是密文密码,不然用户就太危险了,app的运营

如何在游戏客户端和服务器之间精确同步玩家的状态?

欢迎来到unity学习.unity培训.unity企业培训教育专区,这里有很多Unity3D资源.Unity3D培训视频.Unity3D教程.Unity3D常见问题.Unity3D项目源码,[狗刨学习网]unity极致学院,致力于打造业内unity3d培训.学习第一品牌. 假定技能有前摇,攻击,后摇3个阶段. 前摇阶段可以理解为发招前的酝酿或者念几句咒语,攻击阶段可以理解为开始挥刀砍直至砍中目标身上这个时间段,后摇阶段可以理解为收刀恢复攻击姿势的阶段. 我们的技能的连招系统允许在某些技能(称为技

使用HttpURLConnection实现在android客户端和服务器之间传递对象

一般情况下,客户端和服务端的数据交互都是使用json和XML,相比于XML,json更加轻量级,并且省流量,但是,无论我们用json还是用xml,都需要我们先将数据封装成json字符串或者是一个xml字符串然后传输,那么有没有可能我们直接在android客户端上传递一个Object给服务器端呢?答案是肯定的. 我们看一个简单的App注册页面,如下图: 当我们点击注册按钮的时候,将用户的注册信息通过一个Object对象传递到服务器,好,下来我们看看怎么样来传递对象: 首先我们要把用户的注册信息封装

unity客户端与c++服务器之间的简单通讯_1

// 服务器 # pragma once using namespace std; # include <iostream> # include <string> # include <stdio.h> # include <winsock2.h> # pragma comment(lib,”ws2_32.lib”) # include “Tool.h” void main() { WSAData wsadata; SOCKET ListeningSocke

C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 服务器之间的接口通讯功、信息交换

1:当远程调用方法时,会有很多种可能性发生.接口调用之后,发生错误是什么原因发生的?反馈给开发人员需要精确.精准.高效率,这时候若能返回出错状态信息的详细信息,接口之间的调用就会非常顺利,各种复杂问题也就可以迎刃而解. 2:返回接口的类型定义如下参考: //----------------------------------------------------------------- // All Rights Reserved , Copyright (C) 2015 , Hairihan

2015网易校招Java开发工程师(技术架构)在线笔试题

1.  程序和进程的本质区别是? A.在外存和内存存储 B.非顺序和顺序执行机器指令 C.独占使用和分时使用计算机资源 D.静态和动态特征 参考答案分析: 进程与应用程序的区别: 进程(Process)是最初定义在Unix等多用户.多任务操作系统环境下用于表示应用程序在内存环境中基本执行单元的概念.以Unix操作系统 为例,进程是Unix操作系统环境中的基本成分.是系统资源分配的基本单位.Unix操作系统中完成的几乎所有用户管理和资源分配等工作都是通过操作系统 对应用程序进程的控制来实现的.