使用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. python小知识课堂

    啦啦啦 with上下文管理 __class__和type的关系

  2. redis位图巧用,节约内存

    最近要做一个圣诞抽奖活动,需要记录每天用户签到的记录,以前一般都是用普通的字符串数据类型,每个用户的签到用一个 key // 用户10在活动第一天的签到key为record:1:10 $key = & ...

  3. luogu P2701 [USACO5.3]巨大的牛棚Big Barn |动态规划

    题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的 ...

  4. 使用SQL计算宝宝每次吃奶的时间间隔

    需求:媳妇儿最近担心宝宝的吃奶时间不够规律,网上说是正常平均3小时喂奶一次,让我记录下每次的吃奶时间,分析下实际是否偏差很大,好在下次去医院复查时反馈给医生. 此外,还要注意有时候哭闹要吃奶,而实际只 ...

  5. ios高效开发-正确的使用枚举(Enum)

    前言 Enum,也就是枚举,从C语言开始就有了,C++.Java.Objective-C.Swift这些语言,当然都有对应的枚举类型,功能可能有多有少,但是最核心的还是一个—规范的定义代码中的状态.选 ...

  6. 你真的了解JSON吗?

    一.JSON——JavaScript Object Notation JSON 是一种语法用来序列化对象.数组.数值.字符串.布尔值和null .它基于 JavaScript 语法,但与之不同:一些J ...

  7. Java修炼——内部类详解

    内部类详解 定义:将一个类定义在另一个类的内部,该类就称为内部类 类中定义的内部类特点: 内部类作为外部类的成员,可以直接访问外部类的成员 (包括 private 成员),反之则不行. 内部类做为外部 ...

  8. 洛谷P2569 (BZOJ1855)[SCOI2010]股票交易 【单调队列优化DP】

    Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价 ...

  9. BZOJ1014 火星人的prefix

    火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字 ...

  10. Android Studio 3.0下创建menu布局文件的图例

    当开始一个android app的时候,android studio项目中没有看到menu文件夹:如下所示: 当要添加一个按钮时,很多文档上都会说,通过在项目的 res/menu 目录中新增一个 XM ...