用java做后端开发的一个websocket小demo。
效果
后端部分
提供给前端的连接类:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50package message;
import com.google.gson.Gson;
import message.bean.TextMessage;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
"/message/{clientId}") (
public class MessageConnector {
private static MessageConversation conversation = new MessageConversation();
private String clientId;
public void onOpen(@PathParam("clientId") String clientId, Session session) throws IOException {
this.clientId = clientId;
MessageClient existsClient = conversation.findClient(clientId);
if (existsClient != null) {
conversation.unregisterClient(existsClient);
}
conversation.registerClient(new MessageClient(clientId, session));
System.out.println("新的客户端已登入:" + clientId);
}
public void onClose() throws IOException {
conversation.unregisterClient(conversation.findClient(clientId));
System.out.println("客户端已退出:" + clientId);
}
public void onMessage(String message) throws IOException {
System.out.println("收到消息:" + message);
TextMessage textMessage = new Gson().fromJson(message, TextMessage.class);
textMessage.time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
conversation.dispatchMessage(textMessage);
}
public void onError(Session session, Throwable error) {
conversation.unregisterClient(conversation.findClient(clientId));
System.out.println("客户端意外退出:" + clientId);
error.printStackTrace();
}
}
会话类:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34package message;
import com.google.gson.Gson;
import message.bean.TextMessage;
import java.util.HashSet;
import java.util.Set;
public class MessageConversation {
private Set<MessageClient> clients = new HashSet<>();
public MessageConversation() {
}
public void registerClient(MessageClient client) {
clients.add(client);
}
public void unregisterClient(MessageClient client) {
clients.remove(client);
}
public MessageClient findClient(String clientId) {
return clients.stream().filter(client -> client.id.equals(clientId)).findFirst().orElse(null);
}
public void dispatchMessage(TextMessage textMessage) {
clients.forEach(client -> {
if (!textMessage.from.clientId.equals(client.id)) {
client.session.getAsyncRemote().sendText(new Gson().toJson(textMessage));
}
});
}
}
客户端类:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package message;
import javax.websocket.Session;
import java.util.Objects;
public class MessageClient {
public String id;
public Session session;
public String name;
public MessageClient(String id, Session session) {
this.id = id;
this.session = session;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MessageClient that = (MessageClient) o;
return Objects.equals(id, that.id);
}
public int hashCode() {
return Objects.hash(id);
}
}
简单的消息类:1
2
3
4
5
6
7
8
9
10
11
12package message.bean;
public class TextMessage {
public String text;
public From from;
public String time;
public static class From {
public String clientId;
public String name;
}
}
注意事项
依赖了:websocket标准和gson; websocket的jar包在tomcat的lib文件夹下有,gson的jar包需要到maven仓库中下载。
前端部分:
1 |
|
要点:
- 支持按住shift + enter键换行
- 支持按enter快速发送消息
- 客户端标识和昵称都存在了localStorage里面