线上聊天是不是感觉很有意思,为什么他发的消息我能实时收到,有没有想过,做一个服务,让自己的小伙伴用自己的应用聊天呢?
今天我们来一起聊聊,WebSocket实现线上聊天的功能!这个项目时基于jdk1.8,springboot来做的。
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocket.java
@Slf4j
@Component
@ServerEndpoint(value = "/WebSocket/{user}")
public class WebSocket {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static final AtomicInteger OnlineCount = new AtomicInteger(0);
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。
*/
private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<WebSocket>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(@PathParam("user")String user, Session session) {
log.info("新客户端连入,用户id:" + user);
this.session = session;
//加入set中
webSocketSet.add(this);
addOnlineCount(); // 在线数加1
if(user!=null) {
List<String> totalPushMsgs = new ArrayList<String>();
totalPushMsgs.add(user + "连接成功");
if(totalPushMsgs != null && !totalPushMsgs.isEmpty()) {
totalPushMsgs.forEach(e -> sendMessage(e));
}
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
log.info("一个客户端关闭连接");
//从set中删除
webSocketSet.remove(this);
// 在线数减1
subOnlineCount();
}
/**
* 收到客户端消息后调用的方法
* @param message
* 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("用户发送过来的消息为:" + message);
}
/**
* 发生错误时调用
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("websocket出现错误");
error.printStackTrace();
}
public void sendMessage(String message) {
try {
this.session.getBasicRemote().sendText(message);
log.info("推送消息成功,消息为:" + message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 群发自定义消息
*/
public void sendInfo(String message) {
for (WebSocket webSocket : webSocketSet) {
webSocket.sendMessage(message);
}
}
public static synchronized int getOnlineCount() {
return OnlineCount.get();
}
public static synchronized void addOnlineCount() {
// 在线数加1
OnlineCount.incrementAndGet();
}
public static synchronized void subOnlineCount() {
// 在线数加1
OnlineCount.decrementAndGet();
}
}
后端任务结束了,我们来测试下吧,找个谷歌浏览器,按F12,会出现控制台,如图:
在红色箭头写下一下内容回车就会连接上。
var ws = new WebSocket('ws://localhost:8080/WebSocket/zy');
控制台输出如下:
这代表我们已经连上服务了。
怎么从后端发信息给链接的客户端呢?这里木有具体应用,我们就写个定时器然后让它定时发送消息给客户端。
SpringScheduled.java
@Slf4j
@Component
public class SpringScheduled {
@Autowired
private WebSocket webSocket;
@Scheduled(cron="30 * * * * ?")
public void sendElectricSystemHtDto() throws InterruptedException {
ProblemAndAnswer listen = new ProblemAndAnswer();
listen.setType("L");
listen.setMessage("听的动作!");
webSocket.sendInfo(JSONObject.toJSONString(listen));
Thread.sleep(1500);
ProblemAndAnswer problem = new ProblemAndAnswer();
problem.setType("P");
problem.setMessage("自我介绍!");
webSocket.sendInfo(JSONObject.toJSONString(problem));
Thread.sleep(2500);
ProblemAndAnswer answer = new ProblemAndAnswer();
answer.setType("A");
answer.setMessage("您好!我是人工智能小A,有什么是可以帮您吗?");
webSocket.sendInfo(JSONObject.toJSONString(answer));
}
}
测试结果:
这个是群体发送消息,如同广播,当然也可是点对点,这边就介绍这么多吧!剩下的就靠各位探讨了。