基于vert.x与webSocket的简单聊天系统
使用vert.x和webSocket的简单聊天实现
主要的verticle
package com.zhku.analysis.service;
/*
* @author :
* @version : 2018/4/22 21:00.
* 说明:
*/
import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.ServerWebSocket;
import io.vertx.ext.web.Router;
import org.apache.log4j.Logger;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/**
* <pre> <pre>
*/
public class WebSocketVerticle extends AbstractVerticle {
private Logger LOG = Logger.getLogger(this.getClass());
// 保存每一次连接到服务器的通道
private Map<String,ServerWebSocket> connectionMap = new HashMap<>(16);
private int countId = 0;
private Map<String,Integer> userIdMap = new HashMap<>(16);
@Override
public void start() throws Exception{
HttpServer httpServer = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route("/").handler(rct -> {
rct.response().sendFile("html/ws.html");
});
websocketMethod(httpServer);
httpServer.requestHandler(router::accept).listen(8080);
}
private void websocketMethod(HttpServer httpServer) {
httpServer.websocketHandler(webSocket -> {
// 获取每一个链接的ID
String id = webSocket.binaryHandlerID();
// 获取每一个链接用户id自增
// 判断当前连接的ID是否存在于map集合中,如果不存在则添加进map集合中
if (!connectionMap.containsKey(id)) {
connectionMap.put(id,webSocket);
countId++;
userIdMap.put(id,countId);
}
// WebSocket连接
webSocket.frameHandler(handler -> {
String textData = handler.textData();
String currID = webSocket.binaryHandlerID();
// 给非当前连接到服务器的每一个WebSocket连接发送消息
for (Map.Entry<String,ServerWebSocket> entry : connectionMap.entrySet()) {
/* 发送文本消息
文本信息似乎不支持图片等二进制消息
若要发送二进制消息,可用writeBinaryMessage方法
*/
// 当前用户发送了消息
entry.getValue().writeTextMessage("用户"+userIdMap.get(currID)
+"- "+ LocalDateTime.now()+": "+textData);
}
});
// 客户端WebSocket关闭时,将当前ID从map中移除
webSocket.closeHandler(handler -> connectionMap.remove(id));
});
}
}
部署的verticle:
package com.zhku.analysis;
/*
* @author :
* @version : 2018/3/17 18:44.
* 说明:
*/
import com.zhku.analysis.service.UserService;
import com.zhku.analysis.service.WebSocketVerticle;
import com.zhku.analysis.web.RouterVerticle;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import org.apache.log4j.Logger;
/**
* <pre> </pre>
*/
public class MainVerticle {
private Logger LOG = Logger.getLogger(this.getClass());
public static void main(String[] args){
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(WebSocketVerticle.class.getName());
System.out.println("vert.x 成功启动");
}
}
html页面的代码:
<!DOCTYPE html>
<html lang="en" xmlns:text-align="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>WebSocketTest</title>
<script type="text/javascript" src="http://www.w3school.com.cn/jquery/jquery-1.11.1.min.js"></script>
</head>
<body>
<script>
var socket;
if(window.WebSocket){
socket = new WebSocket("ws://localhost:8080/");
// websocket收到消息
socket.onmessage = function(event){
// 如果服务端是写的二进制数据,则此处的blob也是一个二进制对象,提取数据时需要Blob类和FileReader类配合使用
var blob = event.data;
var content = $("#content").html();
var newline = "<br>";
content += newline;
content += blob;
$("#content").html(content);
};
// websocket连接打开
socket.onopen = function (event) {
console.log("websocket 连接打开");
};
// websocket连接关闭
socket.onclose = function (event) {
console.log("websocket 连接关闭");
};
}else{
alert("你的浏览器不支持websocket");
}
function send(message) {
if(!window.WebSocket){
return;
}
if(socket.readyState == WebSocket.OPEN){
socket.send(message);
}else{
alert("websocket连接未打开,请检查网络设置");
}
}
</script>
<h1 text-align: center>vert.x与webSocket的聊天系统</h1>
<h3 text-align: center>---- 请在其他窗口打开localhost:8080进行聊天</h3>
<form onsubmit="return false;" >
<input type="text" name="message">
<input type="button" value="提交" onclick="send(this.form.message.value)">
<div id="content"></div>
</form>
</body>
</html>
页面的位置:
效果图:
项目启动后,在浏览器多个窗口打开 localhost:8080 就可以测试了。