使用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. php: $$str

    这种写法称为可变变量有时候使用可变变量名是很方便的.就是说,一个变量的变量名可以动态的设置和使用.一个普通的变量通过声明来设置,例如: <?php$a = "hello";? ...

  2. 网页采集器-UA伪装

    网页采集器-UA伪装 UA伪装 请求载体身份标识的伪装: User-Agent: 请求载体身份标识,通过浏览器发起的请求,请求载体为浏览器,则该请求的User-Agent为浏览器的身份标识,如果使用爬 ...

  3. 判断一个坐标点是否在封闭曲线内的方法(swift)

    //用playground运行即可 import UIKit var str = "Hello, playground" let lTestPointsOne : [(Double ...

  4. socket实现一个简单的echo服务

    服务端的实现: public class EchoServer{ //创建一个serverSocket private final ServerSocket serverSocket; //创建一个构 ...

  5. 记一次Elasticsearch OOM的优化过程——基于segments force merge 和 store type 转为 niofs

    首选,说明笔者的机器环境(不结合环境谈解决方案都是耍流氓): cpu 32核,内存128G,非固态硬盘: RAID0 (4T * 6),单节点,数据量在700G到1800G,索引15亿~21亿.敖丙大 ...

  6. [TimLinux] JavaScript 中循环执行和定时执行

    1. 两对函数 // 循环执行 // 在每个毫秒数之后,调用函数 var timeid = window.setInterval(函数名, 毫秒数); window.clearInterval(tim ...

  7. acm模板总结

    模板链接 字符串模板 KMP EXKMP Trie 可持久化Trie树+DFS序 01Trie Manacher 字符串哈希 2019上海网络赛G题 17 SA(后缀数组)  最大不重叠相似子串 求两 ...

  8. 2017 CCPC秦皇岛 A题 A Ballon Robot

    The 2017 China Collegiate Programming Contest Qinhuangdao Site is coming! There will be  teams parti ...

  9. CSS去除input和textarea点击选中框

    1.去除chrome等浏览器默认发光边框 input:focus, textarea:focus { outline: none; } 这样textarea在选中的时候,文字会有点移动,解决方法: i ...

  10. 【VUE】自定义组件

    [VUE]自定义组件 转载: ============================================ ======================================== ...