gitee地址: https://gitee.com/equinox166/simple-online-chat
前端:html
核心代码:
socket.onopen = function() {}
用户连接时触发
socket.onmessage = function(e) {}
接收到服务器端传来的信息时触发
socket.onerror = function() {}
连接错误时触发
socket.onclose = function() {}
关闭连接时触发
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>websocket通讯</title>
<style type="text/css">
#ad,#bd {
width: 300px;
height: 200px;
border: solid 1px;
}
</style>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<!-- 用户一:tom -->
<div>
<input id="ai" type="text" placeholder="请输入">
<button id="ab">发送</button>
<div id="ad"></div>
</div>
<script>
var inputa = document.querySelector('#ai')
var buttona = document.querySelector('#ab')
var diva = document.querySelector('#ad')
var chat = {
username : 'tom',
message : '连接'
}
var url = 'ws://127.0.0.1:9090/WebSocketLink/{'+ JSON.stringify(chat) +'}'
var socketa = new WebSocket(url)
socketa.onopen = function() {
diva.innerHTML = diva.innerText + '连接成功'
}
$('#ab').click(function(){
var msg = $('#ai').val()
$('#ai').val("")
var chat = {
username : 'tom',
message : msg
}
socketa.send(JSON.stringify(chat))
})
socketa.onmessage = function(e) {
var chat = e.data
diva.innerHTML = diva.innerText +'/n' + JSON.parse(chat).message
}
socketa.onerror = function() {
diva.innerHTML = diva.innerText + '<br>连接失败'
}
socketa.onclose = function() {
div.innerHTML = diva.innerText + '<br>连接关闭'
}
</script>
<!-- 用户二:jerry -->
<div>
<input id="bi" type="text" placeholder="请输入">
<button id="bb">发送</button>
<div id="bd"></div>
</div>
<script>
var inputb = document.querySelector('#bi')
var buttonb = document.querySelector('#bb')
var divb = document.querySelector('#bd')
var chat = {
username : 'jerry',
message : '连接'
}
var url = 'ws://127.0.0.1:9090/WebSocketLink/{'+ JSON.stringify(chat) +'}'
var socketb = new WebSocket(url)
socketb.onopen = function() {
divb.innerHTML = divb.innerText + '连接成功'
}
$('#bb').click(function(){
var msg = $('#bi').val()
$('#bi').val("")
var chat = {
username : 'jerry',
message : msg
}
socketa.send(JSON.stringify(chat))
})
socketb.onmessage = function(e) {
var chat = e.data
divb.innerHTML = divb.innerText +'/n' + JSON.parse(chat).message
}
socketb.onerror = function() {
divb.innerHTML = divb.innerText + '<br>连接失败'
}
socketb.onclose = function() {
divb.innerHTML = divb.innerText + '<br>连接关闭'
}
</script>
</body>
</html>
写了两个div分别放两个用户,用户信息写死tom和jerry。
使用时直接改chat对象就可以了。
后端:SpringBoot
maven导入:web启动器、webSocket、lombok和JSON工具类依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
<version>5.4.7</version>
</dependency>
ChatServer服务器端代码
ConcurrentHashMap用来存放连接上的用户信息
onLineCount用来计用户数
@onOpen注解表示此方法在用户连接时触发
@onMessage注解表示服务器每次接收到来自用户端的信息时触发
@onClose注解表示每次用户断开连接时触发
@onError注解表示用户连接发生错误时触发
@ServerEndpoint("/WebSocketLink/{userInfo}")
@Component
public class ChatServer {
private static ConcurrentHashMap<String, Chat> map = new ConcurrentHashMap<>();
private static int onLineCount = 0;
@OnOpen
public void onOpen(Session session, @PathParam("userInfo") String userInfo ) {
System.out.println(session);
System.out.println("有用户连接上来了");
System.out.println(userInfo);
Chat chat = JSONUtil.toBean(userInfo, Chat.class);
chat.setSession(session);
System.out.println(chat);
map.put(chat.getUsername(),chat);
}
@OnMessage
public void onMessage(String message) throws IOException {
System.out.println(message);
Chat chat = JSONUtil.toBean(message, Chat.class);
System.out.println(chat);
String username = "tom";
if(chat.getUsername().equals("tom")){
username = "jerry";
}
map.get(username).getSession().getBasicRemote().sendText(JSONUtil.toJsonStr(chat));
}
@OnClose
public void onClose() { }
@OnError
public void one rror(Throwable error) {
error.printStackTrace();
}
public static synchronized int getOnLineCount(){
return onLineCount;
}
public static synchronized void addOnLineCount(){
onLineCount++;
}
public static synchronized void subOnLineCount(){
onLineCount--;
}
}
WebSocketConfig配置类代码
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
Chat实体类代码
@Data
@EqualsAndHashCode(callSuper = false)
public class Chat {
String username;
String message;
Session session;
}