Java实现网页一对一 一对多实时聊天websocket
后台代码 最重要的类
package com.socket.websocket.chat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
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;
/**
* websocket
* @author CHHUANG
*/
@ServerEndpoint("/webSocket/{senderId}") // 该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。
@Component
public class WebChat {
// 用来存放每个客户端对应的ChatAnnotation对象,实现服务端与单一客户端通信的话,使用Map来存放,其中Key可以为用户标识,hashtable比hashmap线程安全
private static Map<String, WebChat> webSocketMap = new Hashtable();
// 与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 连接建立成功调用的方法
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(@PathParam(value="senderId") String senderId, Session session) {
this.session = session;
webSocketMap.put(senderId,this);//加入map中
System.out.println(senderId+"连接加入!当前在线人数为"+getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(@PathParam(value="senderId") String userId) {
webSocketMap.remove(userId);
System.out.println(userId+"关闭连接!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(@PathParam(value="senderId") String senderId, String message, Session session) {
// 群发消息
try {
//将前端发送的 JSON 字符串转换为 JSON 对象
JSONObject jsonMessge = JSON.parseObject(message);
//获取接收者ID列表
JSONArray list = jsonMessge.getJSONArray("userList");
//获取发送者的聊天对象
WebChat userMap = webSocketMap.get(senderId);
//获取发送的消息
String mess=jsonMessge.getString("mess");
//为自己发送一条消息
userMap.sendMessage(mess);
//遍历消息接受者列表
for (Object receiverId : list) {
//获取消息接受者
WebChat receiver = webSocketMap.get(receiverId);
//调用session的发送消息方法 将消息发送到客户端
receiver.sendMessage(mess);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(@PathParam(value="userId") String userId, Session session, Throwable error) {
System.out.println(userId+"发生错误");
error.printStackTrace();
}
/**
* 发送消息
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 发送文件
* @throws IOException
*/
public void sendFile(File file)throws IOException{
this.session.getAsyncRemote().sendObject(file);
}
public static synchronized int getOnlineCount() {
return webSocketMap.size();
}
}
配置类
package com.socket.websocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
System.out.println(">>>>>>>>>>>>>>>>>启用 WebSocket");
return new ServerEndpointExporter();
}
}
pom.xml
<!--websocket连接需要使用到的包-->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- webSocket 结束-->
<!-- fastjson JSON包-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style type="text/css">
input#chat {
width: 410px
}
#console-container {
width: 400px;
}
#console {
border: 1px solid #CCCCCC;
border-right-color: #999999;
border-bottom-color: #999999;
height: 170px;
overflow-y: scroll;
padding: 5px;
width: 100%;
}
#console p {
padding: 0;
margin: 0;
}
</style>
<body>
<div>
<p>
<input type="text" placeholder="type and press enter to chat" id="chat" />
</p>
<div id="console-container">
<div id="console"></div>
</div>
<script type="text/javascript">
var Console = {};
var mess={};
var userList=[];
var senderId=prompt("请输入你的账号");
Console.log = (function(message) {
var console = document.getElementById('console');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.innerHTML = message;
console.appendChild(p);
while (console.childNodes.length > 25) {
console.removeChild(console.firstChild);
}
console.scrollTop = console.scrollHeight;
});
var Chat = {};
Chat.socket = null;
Chat.connect = (function(host) {
if ('WebSocket' in window) {
Chat.socket = new WebSocket(host);
} else if ('MozWebSocket' in window) {
Chat.socket = new MozWebSocket(host);
} else {
Console.log('错误');
return;
}
Chat.socket.onopen = function() {
Console.log('打开连接');
document.getElementById('chat').onkeydown = function(event) {
if (event.keyCode == 13) {
Chat.sendMessage();
}
};
};
Chat.socket.onclose = function() {
document.getElementById('chat').onkeydown = null;
Console.log('关闭.');
};
Chat.socket.onmessage = function(message) {
Console.log(message.data);
};
});
Chat.initialize = function() {
Chat.connect('ws://127.0.0.1:8080/webSocket/'+senderId);
};
Chat.sendMessage = (function() {
var message = document.getElementById('chat').value;
var receiverIds=prompt("请输入接收者账号用逗号分隔");
userList=receiverIds.split(",");
mess.userList=userList;
mess.mess=message;
var strmee=JSON.stringify(mess)
if (message != '') {
//发送
Chat.socket.send(strmee);
//清空输入框
document.getElementById('chat').value='';
}
});
Chat.initialize();
</script>
</div>
</body>
</html>
第一次发帖…复制别人的稍微做了修改 可以把html打开多个页面进行测试
用的是spring boot 有条件的可以在 我的主页去找源码
没条件的去这里 https://pan.baidu.com/s/1DcnrdiSlh1CQAe9SUg5rcg
取件码:hhva