1.依赖
<!-- 引入websocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
2.java后端代码
@ServerEndpoint("/websocket/{username}/{to}")
public class Contact {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static CopyOnWriteArraySet<Contact> webSocketSet = new CopyOnWriteArraySet<Contact>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private static Map<String,Contact> clients = new ConcurrentHashMap<String,Contact>();
private String username; //用户名称
private String to; //一对一发送
private static Map<String,Object> oneTo1 = new HashMap<>();
/*
* 连接成功,调用的方法
*
*/
@OnOpen
public void onOpen(@PathParam("username") String username,@PathParam("to") String to,Session session)
{
System.out.println("to: " + to);
System.out.println("session: " + session);
this.session = session;
webSocketSet.add(this);
addOnlineCount(); //在线数加一
//对应相应人
this.username = username;
for(Contact item:clients.values())
{
if(item.username.equals(username))
{
System.out.println("已经在线了,不用重复添加!" + item.username);
return;
}
}
clients.put(username, this); //使用username,
oneTo1.put(username,to); //保存该用户与其的一对一的关系
System.out.println("用户:" + username);
System.out.println("有新连接加入!当前在线人数为:" + getOnlineCount());
}
/*
* 连接关闭
*
*/
@OnClose
public void onClose() {
clients.remove(username);
System.out.println("连接减一");
webSocketSet.remove(this);
subOnlineCount();
System.out.print("人数减一");
}
/*
* 接收客户端消息的方法
*
*/
@OnMessage
public void onMessage(String message,Session session) throws IOException
{
//消息中带有 to的信息
System.out.println("来自客户端的消息:"+ message);
JSONObject jsonobj = new JSONObject(message);
System.out.println("from 用户:" + jsonobj.get("from"));
System.out.println("发送给 to用户:" + jsonobj.get("to"));
System.out.println(jsonobj.get("msg"));
if(jsonobj.get("to")!=null)
{ String from = (String) jsonobj.get("from");
String me = (String) jsonobj.get("msg");
String to = (String) jsonobj.get("to");
sendMessageTo(me,from,to);
}
// for(Contact item:webSocketSet)
// {
// try {
// item.sendMessage(message);
//
// }catch(IOException e)
// {
// e.printStackTrace();
//
// continue;
// }
// }
}
/*
* 发生错误
*
*/
@OnError
public void onError(Session session,Throwable error)
{
error.printStackTrace();
}
//一对一的发送消息,发送消息给 to
public void sendMessageTo(String message,String from,String to) throws IOException {
System.out.println(from + " 发送消息 " + message + " 给 " + to);
for(Contact item:clients.values())
{
if(item.username.equals(to))
{
String msg = from + ":" + message;
//String msgjson ="{from:"+from+",msg:"+message+",to:"+to+"}";
System.out.println("输出:" + oneTo1.get(from));
item.session.getAsyncRemote().sendText(msg);
}
// if(item.username.equals(from))
// {
// item.session.getAsyncRemote().sendText(message);
// }
}
}
/*
* 发送消息
*
*/
public void sendMessage(String message) throws IOException
{
System.out.println("发送消息..." + message);
for(Contact item:clients.values())
{ //判断是哪个人
// item.session.getAsyncRemote().sendText(message);
}
//this.session.getBasicRemote().sendText(message);
}
/*
* 发送消息给所有
*/
public void sendMessageAll(String message) {
for(Contact item:clients.values()) {
item.session.getAsyncRemote().sendText(message);
}
}
public static synchronized int getOnlineCount()
{
return onlineCount;
}
public static synchronized void addOnlineCount() {
Contact.onlineCount++;
}
public static synchronized void subOnlineCount() {
Contact.onlineCount--;
}
//
public static synchronized Map<String,Contact> getClients(){
return clients;
}
}
3.vue前端代码,methods中代码
websocket(){
//保存username,获取当前用户
this.username = this.$store.getters.getUser.username
console.log(this.username)
console.log(this.user)
if('WebSocket' in window)
{
this.socket = new WebSocket(this.path+this.username+"/"+ this.user)
console.log(this.socket)
this.socket.onopen = this.onopen();
//this.socket.onmessage = this.onmessage();
this.socket.onmessage = evt =>{
//console.log("接收到从后端的信息")
console.log(evt)
this.onmessage(evt)
//this.setMessageInnerHTML(evt.data)
}
//this.socket.onclose = this.onclose();
}
else{
alert("浏览器不支持")
}
},
onopen(){
this.setMessageInnerHTML("连接成功")
},
onclose(){
this.setMessageInnerHTML("websocket连接关闭")
this.socket.onclose();
},
onmessage(evt){
console.log("收到从后端 别人发来 的消息...xx");
this.setMessageInnerHTML(evt.data);
},
closeWebSocket(){
//this.onclose();
console.log("关闭的方法..")
this.onclose();
},
setMessageInnerHTML(innerHtml){
console.log("执行显示.......")
document.getElementById('message').innerHTML += innerHtml + '<br/>';
},
selfMessageInnerHTML(innerHtml)
{
document.getElementById('selfmessage').innerHTML += innerHtml + '<br/>';
},
send(){
this.selfMessageInnerHTML(this.inputmessage)
console.log("发送消息...")
//对消息拼接,
var mess = {"from":this.username,"to":this.user,"msg":this.inputmessage};
mess = JSON.stringify(mess) //转换为让后端能接收的 json格式
console.log(mess)
this.socket.send(mess) //发送给后端
this.inputmessage = "";
},
},