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:当远程调用方法时,会有很多种可能性发生.接口调用之后,发生错误是什么原因发生的?反馈给开发人员需要精确.精准.高效率,这时候若能返回出错状态信息的详细信息,接口之间的调用就会非常顺利,各种复杂问题 ...
随机推荐
- input监听
<h1> 实时监测input中值的变化 </h1> <input type="text" id="username" autoco ...
- Netty学习——protoc的新手使用流程
Netty学习——protoc的新手使用流程 关于学习的内容笔记,记下来的东西等于又过了一次脑子,记录的更深刻一些. 1. 使用IDEA创建.proto文件,软件会提示你安装相应的语法插件 安装成功之 ...
- 循环神经网络(RNN)的改进——长短期记忆LSTM
一:vanilla RNN 使用机器学习技术处理输入为基于时间的序列或者可以转化为基于时间的序列的问题时,我们可以对每个时间步采用递归公式,如下,We can process a sequence ...
- 链接脚本(Linker Script)应用实例(一)使用copy table将函数载入到RAM中运行
将函数载入到RAM中运行需要以下三个步骤: (1)用编译器命令#pragma section "<section name>" <user functions&g ...
- eNSP 简介及基础操作
eNSP 一. eNSP简介 eNSP是一款由华为自主研发的.免费的.可扩展的.图形化操作的网络仿真工具平台,主要对企业网络路由器.交换机及相关物理设备进行软件仿真,支持大型网络模拟.界面如下: 界面 ...
- Python之数据分析工具包介绍以及安装【入门必学】
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 首先我们来看 Mac版 按照需求大家依次安装,如果你还没学到数据分析,建议你 ...
- Bootstrap响应式栅格系统设计
为了方便起见,我们通过1200px宽的屏幕来讲解bootstrap中container.row.col的css属性值为何这样设置的原理 在1200px屏幕中为何container的宽度设置为1170p ...
- 为什么有ASP.NET
最近读了一些文章,总结一下: 在1999年,当时微软的windows系统运行的所有的应用程序都是有组件对象模型为根本基础开发的,用VB来处理数据访问和复杂的用户界面,缺点是不能使用函数指针,因为当时的 ...
- 一篇文章看清楚JDK13的特性!
1.switch优化更新 JDK11以及之前的版本: switch (day) { case MONDAY: case FRIDAY: case SUNDAY: System.out.println( ...
- 如何用Postman做接口测试
postman介绍&测试准备: postman介绍:postman是一个开源的接口测试工具,无论是做单个接口的测试还是整套测试脚本的拨测都非常方便. 前期准备:测试前,需要安装好postman ...