小菜一枚,公司业务使用了基于netty的websocket,奈何不会netty,索性之前了解到一个基于netty的toolkit,也就是Vert.x。
Vert.x是一个基于事件和异步,依托于全异步Java服务器Netty,并扩展了很多其他特性,以其轻量、高性能、支持多语言开发而备受开发者青睐的工具集(注意,不是说的框架,而是工具集)。点击进入Vert.x官网。目前Vert.x以更新到了3.5.0
它支持的语言:Java、JavaScript、Groovy、Ruby、Ceylon、Kotlin、Scala……未来也许会增加更多的语言支持。
言归正传,这个小东西代码不多,仅作为个人学习Vert.x使用,预期实现目标如下:
- 使用Maven搭建Vert.x程序框架
- 使用Vert.x的WebSocket实现一个简易的局域网聊天室(仅支持文本消息)
Vert.x3.5.0因为使用了大量的Java8的特性,比如lambda表达式,所以要求JDK版本为JDK8+
Maven我使用的3.3.9
IDE使用的Intellij IDEA 2017.2
新建一个Maven项目,名称什么的随便
pom.xml文件中引入Vert.x 3.5.0版本的依赖
<dependency>
<groupId>io.vertxgroupId>
<artifactId>vertx-webartifactId>
<version>3.5.0version>
dependency>
引入了vertx-web自动引入了vertx-core,所以不用手动添加core的依赖
import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.ServerWebSocket;
import io.vertx.ext.web.Router;
import java.util.HashMap;
import java.util.Map;
public class WebSocketVerticle extends AbstractVerticle {
// 保存每一个连接到服务器的通道
private Map connectionMap = new HashMap<>(16);
@Override
public void start() throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route("/").handler(routingContext -> {
routingContext.response().sendFile("html/ws.html");
});
websocketMethod(server);
server.requestHandler(router::accept).listen(8080);
}
public void websocketMethod(HttpServer server) {
server.websocketHandler(webSocket -> {
// 获取每一个链接的ID
String id = webSocket.binaryHandlerID();
// 判断当前连接的ID是否存在于map集合中,如果不存在则添加进map集合中
if (!checkID(id)) {
connectionMap.put(id, webSocket);
}
// WebSocket 连接
webSocket.frameHandler(handler -> {
String textData = handler.textData();
String currID = webSocket.binaryHandlerID();
//给非当前连接到服务器的每一个WebSocket连接发送消息
for (Map.Entry entry : connectionMap.entrySet()) {
if (currID.equals(entry.getKey())) {
continue;
}
/* 发送文本消息
文本信息似乎不支持图片等二进制消息
若要发送二进制消息,可用writeBinaryMessage方法
*/
entry.getValue().writeTextMessage(textData);
}
});
// 客户端WebSocket 关闭时,将当前ID从map中移除
webSocket.closeHandler(handler -> connectionMap.remove(id) );
});
}
// 检查当前ID是否已经存在与map中
public boolean checkID(String id) {
return connectionMap.containsKey(id);
}
整个websocket的服务器端代码就这么点。没有用过其它的框架实现过websocket聊天室,不知道代码量如何。但就Vert.x的实现方式来说,个人觉得还是很方便的。
public class Main {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(WebSocketVerticle.class.getName());
}
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocketTesttitle>
<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();
blob += content;
$("#content").html(blob);
};
// 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>
<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>
群推荐:如果对Vert.x技术感兴趣,可以加QQ群: 515203212。
转载请注明出处:http://blog.csdn.net/zhhactj/article/details/78728899