目录
1.用户离开聊天室
跟用户进入聊天室一样,用户离开聊天室会触发OnClose,在OnClose广播我将要离开就可以了,思路跟进入聊天室是一样的,只是广播的内容变了。
@OnClose
public void onClose(){
webSockets.remove(this);
map.remove(session.getId());
System.out.println("有新的断开,总数"+webSockets.size()+"sessionId:"+session.getId());
String content="恭送"+username+"离开聊天室!";
Message message=new Message(content,map);
send(message.toJson());
}
还要在webSockets集合中把这个通道的WebScoket对象除入,同时在map集合中把session和username除去
2.单聊和多聊
思路:先在客户端js中判断选了那几个用户,然后拼成字符串,发送到WebSocket服务器。服务器解析字符串,根据选中的用户来进行广播。
客户端判断:
function send() {
var time=new Date().toLocaleString();
var message = $("#dope").val();
$("#dope").val("");
var htmlstr='<li><div class="answerHead"><img src="img/2.png"></div><div class="answers">'
+'${username}'+' '+time+'<br/>'+message+'</div></li>';
$("#message").append(htmlstr);
var ss = $("#userList :checked");
var to = "";
$.each(ss, function (key, value) {
to += value.getAttribute("value") + "-";
})
console.info(to);
if (ss.size() == 0) {
var obj = {
msg: message,
type: 1
}
} else {
var obj = {
to: to,
msg: message,
type: 2
}
}
var msg = JSON.stringify(obj);
webSocket.send(msg);
}
主要用:var ss=$("#userList :checked")来获取被选中的CheckBox集合。因为在生成用户列表的时候,我们随便生成了CheckBox,CheckBox的value就是每一个通道的sessionId。所以这时候我们要重新把value的值取出来。 用“-”把每一个ID拼装起来 to += value.getAttribute("value") + "-";在客户端传输数据到服务器时,我们也是用对象转成JSON字符串的方式。这个对象包括:1.要广播的信息、2.区分广播还是私聊的type、3.to就是存储要私聊的id集合。在js中定义这个对象,再转成JSON字符串。
因为客户端是用对象转JSON字符串传过来的,在服务器中我们需要把JSON字符串转对象,但是首先我们得有一个跟客户端类型一样的对象。
package com.example.websocket.vo;
public class ContentVo {
private String to;
private String msg;
private Integer type;
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
}
服务器解析字符串:
@OnMessage
public void onMessage(String json){
ContentVo contentVo = gson.fromJson(json, ContentVo.class);
if (contentVo.getType()==1){
//广播
Message message=new Message();
message.setContent(this.username,contentVo.getMsg());
message.setNames(map);
send(message.toJson());
System.out.println(message.toJson());
}else {
//单聊
Message message=new Message();
message.setContent(this.username,contentVo.getMsg());
message.setNames(map);
String to=contentVo.getTo();
String tos[]=to.substring(0,to.length()-1).split("-");
List<String> lists=Arrays.asList(tos);
for (WebSocket webSocket:webSockets){
if (lists.contains(webSocket.session.getId())&&webSocket.session.getId()!=this.session.getId()) {
try {
webSocket.session.getBasicRemote().sendText(message.toJson());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
获得一个选中的sessionID集合,在循环WebSocket集合中,判断该WebSocket对象的SessionID是否在被选中的集合中,如果是就进行发送信息。
还有一点就是自己发的信息是在右侧,接收的信息是在左侧。在此之前,在广播的时候因为在WebSocket对象集合中,存在要发送给别人的这个WebSocket对象,所以会把信息从服务端发送到自己的客户端来。在改这个功能的时候,当一个用户点击发送的时候,是先把这些信息用js填到对话框中,然后服务端广播的时候就忽略发送信息的这个SessionID。