websocket的使用
实际上就是直连,双方用户必须同时在线才可以
前端链接服务器的websocket代码
let webSocket;
if ("WebSocket" in window){
var name=sessionStorage.getItem("name")
var nowURL=window.location
webSocket=new WebSocket("ws://"+nowURL.host+"/ws/"+name)
//建立链接
webSocket.onopen=function (){
console.log("建立链接")
}
//消息接收
webSocket.onmessage=function (evt){
let rec_msg=evt.data;
console.log("收到的消息");
let obj=JSON.parse(rec_msg)
console.log("解析为");
if (obj.textMessage!=undefined) {
$("#divMsgHistory").append(
"<div><div style='float: left;padding: 5px 6px;'>"+obj.fromUser+
":</div><div style='border-radius:10px;background-color: rgb(255,255,255);padding: 5px 6px;float: left'>"
+ obj.textMessage +
"</div></div><div style='clear: both;'></div>")
}
};
webSocket.onclose=function (){
console.log("链接关闭")
}
$("#btnSend").unbind('click').click(function (){
let message={
"message": $("#tbxMsg").val(),
"uname":name,
"to":$("#selTo").val()
}
webSocket.send(JSON.stringify(message))
$("#tbxMsg").val("");
$("#divMsgHistory").append(
"<div style='float: right'>"+
"<div style='border-radius:10px;background-color: rgb(158,234,106);padding: 5px 6px;float: left'>"
+ message.message +
"</div><div style='float: left;padding: 5px 6px;'>:我</div></div><div style='clear: both;'></div>")
})
}
$.get("/userList",
function (result){
$('#selTo').empty();
result.data.forEach(function (item, index, array) {
$('#selTo').append(new Option(item, item));
});
layui.form.render('select', 'msgSendForm');
})
后端关于websocket代码
@Component
@ServerEndpoint("/ws/{uname}")
public class WebSocket {
public static int onlineNumber=0;
private static Map<String, WebSocket> clients=new ConcurrentHashMap<String, WebSocket>();
private Session session;
private String uname;
private static Controller userController;
// private static Producers producers=new Producers();
// private static Consumers consumers=new Consumers();
@Autowired
public void setRedisService (Controller userController){
WebSocket.userController= userController;
}
@OnOpen
public void onOpen(@PathParam("uname") String uname,Session session) throws JMSException {
onlineNumber++;
System.out.println("现在链接的客户id"+session.getId()+";用户名:"+uname);
this.uname=uname;
this.session=session;
System.out.println("有新链接加入 当前在线人数:"+onlineNumber);
Map<String,Object> map=new HashMap<>();
map.put("messageType",1);
map.put("uname",uname);
sendMessageAll(JSON.toJSONString(map),uname);
clients.put(uname,this);
Map<String,Object> map2=new HashMap<>();
map2.put("messageType",3);
Set<String> set=clients.keySet();
map2.put("onlineUsers",set);
sendMessageTo(JSON.toJSONString(map2),uname);
}
@OnClose
public void onClose() throws JMSException {
onlineNumber--;
clients.remove(uname);
//链接下线,清除登录
/*
* 问题:关闭消息弹窗时将redis退出了登录
* */
//serController.autologout(uname);
try {
Map<String, Object> map1 = new HashMap<>();
map1.put("messageType", 2);
map1.put("onlineUsers", clients.keySet());
map1.put("uname", uname);
sendMessageAll(JSON.toJSONString(map1), uname);
} catch (Exception ex) {
System.out.println(uname + "下线的时候通知所有人发生了错误");
}
System.out.println("有连接关闭! 当前在线人数" + onlineNumber);
/***
* mq
*/
// consumers.closeConn();
}
@OnMessage
public void onMessage(String message,Session session){
try {
JSONObject jsonObject = JSON.parseObject(message);
String textMessage = jsonObject.getString("message");
String from = jsonObject.getString("uname");
String to = jsonObject.getString("to");
Map<String, Object> mp1 = new HashMap<>();
mp1.put("messageType", 4);
mp1.put("textMessage", textMessage);
mp1.put("fromUser", from);
if (to.equals("ALL")) {
mp1.put("toUser", "所有人");
sendMessageAll(JSON.toJSONString(mp1), from);
} else {
mp1.put("toUser", to);
sendMessageTo(JSON.toJSONString(mp1), to);
}
} catch (Exception ex) {
System.out.println("发生错误");
}
}
@OnError
public void onError(Session session,Throwable error){
System.out.println("服务器发生错误"+error.getMessage());
}
public void sendMessageTo(String message, String uname) {
for (WebSocket item : clients.values()) {
if (item.uname.equals(uname)) {
item.session.getAsyncRemote().sendText(message);
break;
}
}
}
private void sendMessageAll(String message, String username) {
for (WebSocket item : clients.values()) {
item.session.getAsyncRemote().sendText(message);
}
}
public static synchronized int getOnlineNumber() {
return onlineNumber;
}
}
源码包链接(仅websocket版)
https://download.csdn.net/download/Caiabcd/20627381
activemq博文
https://download.csdn.net/download/Caiabcd/20627381
源码包链接(websocket+activemq)
https://download.csdn.net/download/Caiabcd/20628919?spm=1001.2014.3001.5503
遇到的错误信息
Error creating bean with name 'serverEndpointExporter' defined in class
path resource [com/XXXXXXXXXXXXXXXXXXXXXXXX/WebSocketConfigure.class]:
Invocation of init method failed; nested exception is java.lang.IllegalStateException:
javax.websocket.server.ServerContainer not available
解决方式一
检查依赖项,websocket默认针对的是springboot默认的service---》tomcat
切记使用jetty也会报以上错误
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
解决方式二
https://blog.csdn.net/kxj19980524/article/details/88751114