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

前端页面

 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fun"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:set var="baseurl" value="${pageContext.request.contextPath}/"></c:set> <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>web_socket</title> <script type="text/javascript" src="${baseurl}static/js/jquery-2.1.1.js"></script>
<style type="text/css">
.connector {width: 500px;}
</style>
</head>
<body>
Welcome
<br/>
<input id="text" type="text"/>
<button onclick="sendToOne(10008)">发消息给个人</button>
<button onclick="sendToAll(0)">发消息给所有人</button>
<hr/>
<button onclick="closeWebSocket()">关闭WebSocket连接</button>
<hr/>
<div id="message"></div>
</body>
<script type="text/javascript">
var websocket = null;
var host = document.location.host; //判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
console.info("浏览器支持Websocket");
websocket = new WebSocket('ws://'+host+'/${baseurl}/webSocketServer/${userID}');
} else {
console.info('当前浏览器 Not support websocket');
} //连接发生错误的回调方法
websocket.onerror = function() {
console.info("WebSocket连接发生错误");
setMessageInnerHTML("WebSocket连接发生错误");
} //连接成功建立的回调方法
websocket.onopen = function() {
console.info("WebSocket连接成功");
setMessageInnerHTML("WebSocket连接成功");
} //接收到消息的回调方法
websocket.onmessage = function(event) {
console.info("接收到消息的回调方法");
console.info("这是后台推送的消息:"+event.data);
setMessageInnerHTML(event.data);
console.info("webSocket已关闭!");
} //连接关闭的回调方法
websocket.onclose = function() {
setMessageInnerHTML("WebSocket连接关闭");
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
closeWebSocket();
} //关闭WebSocket连接
function closeWebSocket() {
websocket.close();
} //将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
} //发送消息给其他客户端
function sendToOne(receiverId) {
var messageContent = document.getElementById('text').value;
var message = {};
message.senderId = "${userID}";
message.receiverId = receiverId;
message.messageContent = messageContent;
websocket.send(JSON.stringify(message));
} //发送消息给所有人
function sendToAll() {
var messageContent = document.getElementById('text').value;
var message = {};
message.senderId = "${userID}";
message.receiverId = "0";
message.messageContent = messageContent;
websocket.send(JSON.stringify(message));
}
</script>
</html>

后台代码

 import java.util.Date;

 public class WebSocketMessage {

     /**
* 发送者ID
*/
private String senderId; /**
* 接受者ID, 如果为0, 则发送给所有人
*/
private String receiverId; /**
* 会话内容
*/
private String messageContent; /**
* 发送时间
*/
private Date sendTime; public String getSenderId() {
return senderId;
} public void setSenderId(String senderId) {
this.senderId = senderId;
} public String getReceiverId() {
return receiverId;
} public void setReceiverId(String receiverId) {
this.receiverId = receiverId;
} public String getMessageContent() {
return messageContent;
} public void setMessageContent(String messageContent) {
this.messageContent = messageContent;
} public Date getSendTime() {
return sendTime;
} public void setSendTime(Date sendTime) {
this.sendTime = sendTime;
} }
 import javax.servlet.http.HttpServletResponse;

 import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; @Controller
@RequestMapping("webSocket")
public class WebSocketController { @RequestMapping(value = "messagePage/{userID}")
public ModelAndView messagePage(@PathVariable String userID, HttpServletResponse response) {
ModelAndView mav = new ModelAndView();
mav.addObject("userID", userID);
mav.setViewName("web_socket");
return mav;
}
}
 import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint; import com.alibaba.fastjson.JSON;
import com.utime.facade.model.systemplate.WebSocketMessage; @ServerEndpoint("/webSocketServer/{userID}")
public class WebSocketServer {
// 连接客户端数量
private static int onlineCount = 0;
// 所有的连接客户端
private static Map<String, WebSocketServer> clients = new ConcurrentHashMap<String, WebSocketServer>();
// 当前客户端连接的唯一标示
private Session session;
// 当前客户端连接的用户ID
private String userID; /**
* 客户端连接服务端回调函数
*
* @param userID 用户ID
* @param session 会话
* @throws IOException
*/
@OnOpen
public void onOpen(@PathParam("userID") String userID, Session session) throws IOException {
this.userID = userID;
this.session = session; addOnlineCount();
clients.put(userID, this);
System.out.println("WebSocket日志: 有新连接加入!当前在线人数为" + getOnlineCount());
} @OnClose
public void onClose() throws IOException {
clients.remove(userID);
subOnlineCount();
System.out.println("WebSocket日志: 有一连接关闭!当前在线人数为" + getOnlineCount());
} /**
* 接受到来自客户端的消息
*
* @param message
* @throws IOException
*/
@OnMessage
public void onMessage(String message) throws IOException {
System.out.println("WebSocket日志: 来自客户端的消息:" + message);
WebSocketMessage webSocketMessage = JSON.parseObject(message, WebSocketMessage.class); // 发送消息给所有客户端
if ("0".equals(webSocketMessage.getReceiverId())) {
for (WebSocketServer item : clients.values()) {
item.session.getAsyncRemote().sendText(webSocketMessage.getMessageContent());
System.out.println("WebSocket日志: ID为"+ webSocketMessage.getSenderId() +"的用户给ID为"+ item.userID +"的客户端发送:" + webSocketMessage.getMessageContent());
}
} else { // 发送消息给指定ID的客户端
for (WebSocketServer item : clients.values()) {
if (item.userID.equals(webSocketMessage.getReceiverId())){
// 发消息给指定客户端
item.session.getAsyncRemote().sendText(webSocketMessage.getMessageContent());
System.out.println("WebSocket日志: ID为"+ webSocketMessage.getSenderId() +"的用户给ID为"+ item.userID +"的客户端发送:" + webSocketMessage.getMessageContent());
if (!webSocketMessage.getSenderId().equals(webSocketMessage.getReceiverId())) {
// 发消息给自己
this.session.getAsyncRemote().sendText(webSocketMessage.getMessageContent());
System.out.println("WebSocket日志: ID为"+ webSocketMessage.getSenderId() +"的用户给ID为"+ this.userID +"的客户端发送:" + webSocketMessage.getMessageContent());
}
break;
}
}
}
} /**
* 服务端报错了
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("WebSocket日志: 发生错误");
error.printStackTrace();
} /**
* 客户端连接数+1
*/
public static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
} /**
* 客户端连接数-1
*/
public static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
} public static synchronized int getOnlineCount() {
return onlineCount;
} public static synchronized Map<String, WebSocketServer> getClients() {
return clients;
}
}

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

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

  1. WEB客户端和服务器

    # encoding=utf-8 #python 2.7.10 #xiaodeng #HTTP权威指南 #HTTP协议:超文本传输协议是在万维网上进行通信时所使用的协议方案. #WEB客户端和服务器: ...

  2. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

  3. Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装

    在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...

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

    服务器: 1.与客户端的交流手段多是I/O流的方式 2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接 3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输 ...

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

    Android客户端与服务器进行数据传输时,一般会涉及到两类数据的加密情况,一类是只有创建者才能知道的数据,比如密码:另一类是其他比较重要的,但是可以逆向解密的数据. 第一类:密码类的数据,为了让用户 ...

  6. java Activiti6 工作流引擎 websocket 即时聊天 SSM源码 支持手机即时通讯聊天

    即时通讯:支持好友,群组,发图片.文件,消息声音提醒,离线消息,保留聊天记录 (即时聊天功能支持手机端,详情下面有截图) 工作流模块---------------------------------- ...

  7. Android开发,java开发程序员常见面试题,求100-200之间的质数,java逻辑代码

    public class aa{ public static void main (String args []){ //author:qq986945193 for (int i = 100;i&l ...

  8. 客户端与服务器之间通信收不到信息——readLine()

    写服务器端和客户端之间通信,结果一直读取不到信息,在https://blog.csdn.net/yiluxiangqian7715/article/details/50173573 上找到了原因:使用 ...

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

    1:当远程调用方法时,会有很多种可能性发生.接口调用之后,发生错误是什么原因发生的?反馈给开发人员需要精确.精准.高效率,这时候若能返回出错状态信息的详细信息,接口之间的调用就会非常顺利,各种复杂问题 ...

随机推荐

  1. 使用Feign访问接口

     添加主要依赖 使用Feign访问接口的配置,如果服务不在Eureka上,可以不加Eureka的依赖,用在FeignClient上指定url的方式访问 dependencies { compile(' ...

  2. Spring Cloud系列-Zuul网关集成JWT身份验证

    前言 这两三年项目中一直在使用比较流行的spring cloud框架,也算有一定积累,打算有时间就整理一些干货与大家分享. 本次分享zuul网关集成jwt身份验证 业务背景 项目开发少不了身份认证,j ...

  3. python字符串的特性及相关应用

    一.字符串定义 字符串是 Python 中最常用的数据类型.用单引号(' '),双引号(" ")或者三引号(''' ''')括起来的数据称为字符串(其中,使用三引号的字符串可以横跨 ...

  4. IOS之文件夹创建、删除,图片在本地的保存和加载

    本文转自http://blog.csdn.net/toddmi/article/details/8204102 = (NSCachesDirectory, NSUserDomainMask, YES) ...

  5. Python获取 bing 地图发布自己的 TMS 服务(二)解决海量瓦片存取问题

    金字塔结构的瓦片数量有多大 以目前互联网常用的WebMecator为例 第一层:4幅256*256影像瓦片(JPG或PNG等) 第二层:42 第三层:43 依次类推比如计算第1层至第18层的瓦片总数目 ...

  6. vs code:sync setting 插件

    sync setting 是同步设置插件 第一步:A机器上下载插件 第二步:通过git生成 token user(个人中心) --> Settings --> Developer sett ...

  7. 【CentOS7】curl命令

    [CentOS7]curl命令 转载: 参考 https://www.thegeekstuff.com/2012/04/curl-examples/ http://www.cnblogs.com/gb ...

  8. 3个Spring Boot项目调优的方式

    前言 作为一名工程师,项目调优这事,是必须得熟练掌握的事情. 在SpringBoot项目中,调优主要通过配置文件和配置JVM的参数的方式进行.   一.修改配置文件 关于修改配置文件applicati ...

  9. sql语句对int类型进行模糊查询

    重点:select * from course where cast(courseId as char) like '%118%'; 首先可以将int类型转换为string类型的值再进行模糊查询,用方 ...

  10. super()派生使用中的常见两个错误

    """ super()派生可以继承父类的属性 --super()派生继承父类的语法是:super().__init__() --super().__init__()中的_ ...