今天由于项目需要,所以看了下websocket,参考了很多博主的博客,如有雷同请谅解,在这里记录一下从一无所知到实现的过程。
websocket的优点和作用百度一大堆就不说了,直接干。
websocket的创建方式有两种,一种比较简单就是基于服务器的,一种基于springmvc的。这里使用的是基于服务器的。
1、在maven中依赖javaee的jar包
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<scope>provided</scope>
</dependency>
2、创建简单的jsp页面
<%@ page language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>java实现多窗口聊天室</title>
</head>
<body>
聊天室1:<input id="room1" type="text"/>
<br/>
<button onclick="send1()">发送消息</button><button onclick="quitRoom1()">退出聊天室</button>
<hr/><div id="message1"></div><hr/>
<br/>
<br/>
聊天室2:<input id="room2" type="text"/>
<br/>
<button onclick="send2()">发送消息</button><button onclick="quitRoom2()">退出聊天室</button>
<hr/><div id="message2"></div><hr/>
<br/>
<br/>
</body>
<script type="text/javascript">
var websocket1 = new WebSocket("ws://localhost.1.3.26:8087/platform_war_exploded/websocket/1");//第一个聊天室
var websocket2 = new WebSocket("ws://localhost:8087/platform_war_exploded/websocket/2");//第二个聊天室
//连接发生异常的回调方法
websocket1.onerror = function () {
showMessage1("WebSocket连接失败");
};
//连接成功建立的回调方法
websocket1.onopen = function () {
showMessage1("WebSocket连接成功");
}
//接收到消息的回调方法
websocket1.onmessage = function (data) {
showMessage1(data.data);
}
//连接关闭的回调方法
websocket1.onclose = function () {
showMessage1("WebSocket连接关闭");
}
//连接发生异常的回调方法
websocket2.onerror = function () {
showMessage2("WebSocket连接失败");
};
//连接成功建立的回调方法
websocket2.onopen = function () {
showMessage2("WebSocket连接成功");
}
//接收到消息的回调方法
websocket2.onmessage = function (data) {
showMessage2(data.data);
}
//连接关闭的回调方法
websocket2.onclose = function () {
showMessage2("WebSocket连接关闭");
}
function showMessage1(msg) {
document.getElementById('message1').innerHTML += msg + '<br/>';
}
function showMessage2(msg) {
document.getElementById('message2').innerHTML += msg + '<br/>';
}
function send1() {
var message = document.getElementById('room1').value;
websocket1.send(message);
}
function send2() {
var message = document.getElementById('room2').value;
websocket2.send(message);
}
//窗口关闭调用断开websocket服务
window.onbeforeunload = function () {
websocket1.close();
websocket2.close();
}
//退出聊天室
function quitRoom1() {
websocket1.close();
}
//退出聊天室
function quitRoom2() {
websocket2.close();
}
</script>
</html>
3、定义后端代码
package com.xlkh.platform.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/**
* @ServerEndpoint 注解是websocket的注解,用来给用户去访问(前台创建websocket连接的地址)
* roomNum就是聊天室的房间号
*/
@ServerEndpoint("/websocket/{roomNum}")
public class HelloWebsocket {
//CopyOnWriteArraySet<HelloWebsocket>用来存放每个客户端的HelloWebsocket对象
private static Map<String, CopyOnWriteArraySet<HelloWebsocket>> webSocketSets = new HashMap<String, CopyOnWriteArraySet<HelloWebsocket>>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 连接建立成功调用的方法
*
* @param roomNum 聊天室的房间号
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(@PathParam("roomNum") String roomNum, Session session) {
this.session = session;
//基于没一个房间创建一个webSocketSet 放入webSocketSets中key为房间号,此处判断是否有当前房间,
//如果没有需创建,如果有将当前连接用户放入该房间好对应的CopyOnWriteArraySet中
if (webSocketSets.containsKey(roomNum)) {
webSocketSets.get(roomNum).add(this);
} else {
CopyOnWriteArraySet<HelloWebsocket> webSocketSet = new CopyOnWriteArraySet<HelloWebsocket>();
webSocketSet.add(this);
webSocketSets.put(roomNum, webSocketSet);
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(@PathParam("roomNum") String roomNum) {
CopyOnWriteArraySet<HelloWebsocket> set = webSocketSets.get(roomNum);
set.remove(this);
}
/**
* 收到客户端消息后调用的方法
*
* @param roomNum 当前房间号
* @param message 消息内容
*/
@OnMessage
public void onMessage(@PathParam("roomNum") String roomNum, String message) {
System.out.println("当前房间号:" + roomNum);
System.out.println("消息内容:" + message);
CopyOnWriteArraySet<HelloWebsocket> helloWebsockets = webSocketSets.get(roomNum);
//群发消息
for (HelloWebsocket item : helloWebsockets) {
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
/**
* 发生错误时调用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("websocket异常,异常信息如下:");
error.printStackTrace();
}
/**
* 根据当前用户的session去发送消息
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
}
4、效果展示