Java开发之使用websocket实现web客户端与服务器之间的实时通讯
使用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客户端与服务器之间的实时通讯的更多相关文章
- WEB客户端和服务器
# encoding=utf-8 #python 2.7.10 #xiaodeng #HTTP权威指南 #HTTP协议:超文本传输协议是在万维网上进行通信时所使用的协议方案. #WEB客户端和服务器: ...
- Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理
在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...
- Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...
- 用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰
服务器: 1.与客户端的交流手段多是I/O流的方式 2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接 3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输 ...
- Android:客户端和服务器之间传输数据加密
Android客户端与服务器进行数据传输时,一般会涉及到两类数据的加密情况,一类是只有创建者才能知道的数据,比如密码:另一类是其他比较重要的,但是可以逆向解密的数据. 第一类:密码类的数据,为了让用户 ...
- java Activiti6 工作流引擎 websocket 即时聊天 SSM源码 支持手机即时通讯聊天
即时通讯:支持好友,群组,发图片.文件,消息声音提醒,离线消息,保留聊天记录 (即时聊天功能支持手机端,详情下面有截图) 工作流模块---------------------------------- ...
- Android开发,java开发程序员常见面试题,求100-200之间的质数,java逻辑代码
public class aa{ public static void main (String args []){ //author:qq986945193 for (int i = 100;i&l ...
- 客户端与服务器之间通信收不到信息——readLine()
写服务器端和客户端之间通信,结果一直读取不到信息,在https://blog.csdn.net/yiluxiangqian7715/article/details/50173573 上找到了原因:使用 ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 服务器之间的接口通讯功、信息交换
1:当远程调用方法时,会有很多种可能性发生.接口调用之后,发生错误是什么原因发生的?反馈给开发人员需要精确.精准.高效率,这时候若能返回出错状态信息的详细信息,接口之间的调用就会非常顺利,各种复杂问题 ...
随机推荐
- Spring Cloud Gateway - 路由法则
1. After Route Predicate Factory 输入一个参数:时间,匹配该时间之后的请求,示例配置: spring: cloud: gateway: routes: - id: af ...
- js杂项积累
主要内容: 一 浏览器重定向Http请求跨域 二 html select标签 可以设置属性multipe,变为多选 三 document.wirte只应在script标签的顶层代码中使用.不能放在函数 ...
- k 近邻算法解决字体反爬手段|效果非常好
字体反爬,是一种利用 CSS 特性和浏览器渲染规则实现的反爬虫手段.其高明之处在于,就算借助(Selenium 套件.Puppeteer 和 Splash)等渲染工具也无法拿到真实的文字内容. 这种反 ...
- 王晶:华为云OCR文字识别服务技术实践、底层框架及应用场景 | AI ProCon 2019
演讲嘉宾 | 王晶(华为云人工智能高级算法工程师王晶) 出品 | AI科技大本营(ID:rgznai100) 近期,由 CSDN 主办的 2019 中国AI 开发者大会(AI ProCon 2019) ...
- 转:浅谈Spring的PropertyPlaceholderConfigurer
大型项目中,我们往往会对我们的系统的配置信息进行统一管理,一般做法是将配置信息配置与一个cfg.properties的文件中,然后在我们系统初始化的时候,系统自动读取cfg.properties配置文 ...
- fastDfs-理解安装,一篇就够了
觉得可以,点关注 contos7 fastdfs-5.11 fastdfs-nginx-module-1.20 libfastcommon-1.0.40 nginx-1.12.0 在百度网盘可以找到对 ...
- [TimLinux] CSS pre超长自动换行
使用css样式值: pre { white-space: pre-wrap; word-wrap: break-word; }
- ARTS-S centos修改hostname
hostnamectl set-hostname newhostname 重启
- 【HTTP】402- 深入理解http2.0协议,看这篇就够了!
本文字数:3825字 预计阅读时间:20分钟 导读 http2.0是一种安全高效的下一代http传输协议.安全是因为http2.0建立在https协议的基础上,高效是因为它是通过二进制分帧来进行数据传 ...
- SpringAOP在web应用中的使用
之前的aop是通过手动创建代理类来进行通知的,但是在日常开发中,我们并不愿意在代码中硬编码这些代理类,我们更愿意使用DI和IOC来管理aop代理类.Spring为我们提供了以下方式来使用aop框架 一 ...