增加zheng-message技术选型

This commit is contained in:
zhangshuzheng 2018-11-15 14:09:28 +08:00
parent 2371580bc0
commit a8e1bab2cb
18 changed files with 5905 additions and 78 deletions

10
zheng-message/README.md Normal file
View File

@ -0,0 +1,10 @@
# zheng-message
实时通知系统
## 技术选型
后端https://github.com/mrniko/netty-socketio
前端https://socket.io/

View File

@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Demo Chat</title>
<link href="bootstrap.css" rel="stylesheet">
<style>
body {
padding:20px;
}
#console {
height: 400px;
overflow: auto;
}
.username-msg {color:orange;}
.connect-msg {color:green;}
.disconnect-msg {color:red;}
.send-msg {color:#888}
</style>
<script src="js/socket.io/socket.io.js"></script>
<script src="js/moment.min.js"></script>
<script src="js/jquery-1.7.2.min.js"></script>
<script>
var userName = 'user' + Math.floor((Math.random()*1000)+1);
var socket = io.connect('http://localhost:9092');
socket.on('connect', function() {
output('<span class="connect-msg">Client has connected to the server!</span>');
});
socket.on('message', function(data, ackServerCallback) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
if (ackServerCallback) {
// send ack data to server
ackServerCallback('server message was delivered to client!');
}
});
socket.on('disconnect', function() {
output('<span class="disconnect-msg">The client has disconnected!</span>');
});
socket.on('ackevent2', function(data, ackServerCallback, arg1) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
if (ackServerCallback) {
ackServerCallback('server message was delivered to client!');
}
});
socket.on('ackevent3', function(data, ackServerCallback) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
if (ackServerCallback) {
ackServerCallback();
}
});
function sendDisconnect() {
socket.disconnect();
}
function sendMessage() {
var message = $('#msg').val();
$('#msg').val('');
var jsonObject = {'@class': 'com.corundumstudio.socketio.demo.ChatObject',
userName: userName,
message: message};
socket.emit('ackevent1', jsonObject, function(arg1, arg2) {
alert("ack from server! arg1: " + arg1 + ", arg2: " + arg2);
});
}
function output(message) {
var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div>");
$('#console').prepend(element);
}
$(document).keydown(function(e){
if(e.keyCode == 13) {
$('#send').click();
}
});
</script>
</head>
<body>
<h1>Netty-socketio Demo Chat</h1>
<br/>
<div id="console" class="well">
</div>
<form class="well form-inline" onsubmit="return false;">
<input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/>
<button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
</form>
</body>
</html>

View File

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Demo Chat</title>
<link href="bootstrap.css" rel="stylesheet">
<style>
body {
padding:20px;
}
#console {
height: 400px;
overflow: auto;
}
.username-msg {color:orange;}
.connect-msg {color:green;}
.disconnect-msg {color:red;}
.send-msg {color:#888}
</style>
<script src="js/socket.io/socket.io.js"></script>
<script src="js/moment.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var socket = io.connect('http://localhost:9092');
socket.on('connect', function() {
alert('socketio client connected');
});
socket.on('msg', function(file) {
var arrayBuffer = new Uint8Array(file).buffer;
var blob = new Blob([arrayBuffer]);
var imgList = $('ul#img-list');
var li = $('<li/>').appendTo(imgList);
$('<div/>').text(file.name).appendTo(li);
var img = $('<img/>').appendTo(li);
var reader = new FileReader();
reader.onload = (function(aImg) {
return function(e) {
aImg.attr('src', e.target.result);
aImg.attr('width', 150);
};
})(img);
reader.readAsDataURL(blob);
});
$(document).ready(function() {
var fileInput = $('#file-field');
fileInput.bind({
change: function() {
displayFiles(this.files);
}
});
function displayFiles(files) {
$.each(files, function(i, file) {
if (!file.type.match(/image.*/)) {
return true;
}
var reader = new FileReader();
reader.onload = function(e) {
socket.emit('msg', e.target.result);
};
reader.readAsArrayBuffer(file);
});
}
});
</script>
</head>
<body>
Please upload any image file.
<br/>
<br/>
<div>
<input type="file" name="file" id="file-field" />
</div>
<div id="img-container">
<ul id="img-list"></ul>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Demo Chat</title>
<link href="bootstrap.css" rel="stylesheet">
<style>
body {
padding:20px;
}
#console {
height: 400px;
overflow: auto;
}
.username-msg {color:orange;}
.connect-msg {color:green;}
.disconnect-msg {color:red;}
.send-msg {color:#888}
</style>
<script src="js/socket.io/socket.io.js"></script>
<script src="js/moment.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var userName = 'user' + Math.floor((Math.random()*1000)+1);
var socket = io.connect('http://localhost:9092');
socket.on('connect', function() {
output('<span class="connect-msg">Client has connected to the server!</span>');
});
socket.on('chatevent', function(data) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
});
socket.on('disconnect', function() {
output('<span class="disconnect-msg">The client has disconnected!</span>');
});
function sendDisconnect() {
socket.disconnect();
}
function sendMessage() {
var message = $('#msg').val();
$('#msg').val('');
socket.emit('chatevent', {userName: userName, message: message});
}
function output(message) {
var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div>");
$('#console').prepend(element);
}
$(document).keydown(function(e){
if(e.keyCode == 13) {
$('#send').click();
}
});
</script>
</head>
<body>
<h1>Netty-socketio Demo Chat</h1>
<br/>
<div id="console" class="well">
</div>
<form class="well form-inline" onsubmit="return false;">
<input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/>
<button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
</form>
</body>
</html>

View File

@ -1,83 +1,94 @@
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>实时推送系统前端示例</title>
<style>
#main{width:100%;height:400px;margin:0 auto;}
.namespace{width:100%;height:400px;background:#000;}
.title{width:100%;height:40px;font-size:0;background:#666;}
.input,.button{float:left;height:40px;border:none;background:none;outline:none;color:#fff;}
.input{width:25%;text-indent:10px;font-weight:bold;}
.button{width:10%;cursor:pointer;}
#token{width:20%;}
#env{background:rgb(194, 53, 49);}
.messages{width:100%;height:340px;overflow-y:auto;font-size:12px;line-height:2em;color:#fff;}
.messages li{list-style-type:none;}
.messages .connect{color:#00cc00;}
.messages .warn{color:#cccc00;}
.messages .disconnect{color:#cc0000;}
table{width:100%;border-collapse:collapse;border:solid #ccc;border-width:1px 0 0 1px}
table th,table td{border:solid #ccc;border-width:0 1px 1px 0;padding:14px;text-align:center}
</style>
</head>
<body>
<div id="main">
<div class="namespace">
<div class="title">
<select id="env" class="input">
<option value="http://localhost:8882">开发环境</option>
</select>
<input id="namespace" class="input" type="text" placeholder="namespace" value=""/>
<input id="token" class="input" type="text" placeholder="token" value=""/>
<input id="connect" class="button" type="button" value="连接"/>
<input id="send" class="button" type="button" value="发言"/>
<input id="disconnect" class="button" type="button" value="断开"/>
</div>
<div class="messages">
<ul id="list">
</ul>
</div>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/socket.io/2.1.1/socket.io.js"></script>
<script type="text/javascript">
$(function() {
// SocketIO客户端
var socket;
$('#connect').click(function() {
// 获取token请求业务系统接口
var token = $('#token').val();
// 创建socketio连接
socket = io.connect($('#env').val() + $('#namespace').val() + '?token=' + token);
socket.on('connect', function() {
$('#list').prepend('<li class="connect">已连接服务器!</li>');
});
socket.on('message', function(data, ackServerCallback) {
$('#list').prepend('<li class="data">收到服务器消息:' + JSON.stringify(data) + '</li>');
if (ackServerCallback) {
ackServerCallback();
<meta charset="utf-8" />
<title>Demo Chat</title>
<link href="bootstrap.css" rel="stylesheet">
<style>
body {
padding:20px;
}
#console {
height: 400px;
overflow: auto;
}
.username-msg {color:orange;}
.connect-msg {color:green;}
.disconnect-msg {color:red;}
.send-msg {color:#888}
</style>
<script src="js/socket.io/socket.io.js"></script>
<script src="js/moment.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var userName = 'user' + Math.floor((Math.random()*1000)+1);
var socket = io.connect('http://localhost:9092');
socket.on('connect', function() {
output('<span class="connect-msg">Client has connected to the server!</span>');
});
socket.on('chatevent', function(data) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
});
socket.on('disconnect', function() {
output('<span class="disconnect-msg">The client has disconnected!</span>');
});
function sendDisconnect() {
socket.disconnect();
}
});
socket.on('connect_error', function(error) {
$('#list').prepend('<li class="warn">连接服务器失败!</li>');
console.log(error);
});
socket.on('disconnect', function() {
$('#list').prepend('<li class="disconnect">已断开服务器!</li>');
});
$('#send').click(function() {
socket.emit('message', {userName: 'userName', message: new Date()});
});
$('#disconnect').click(function() {
socket.close();
});
// 防止重复连接
$(this).attr('disabled','disabled');
function sendMessage() {
var message = $('#msg').val();
$('#msg').val('');
var jsonObject = {userName: userName,
message: message};
socket.emit('chatevent', jsonObject);
}
function output(message) {
var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div>");
$('#console').prepend(element);
}
$(document).keydown(function(e){
if(e.keyCode == 13) {
$('#send').click();
}
});
});
</script>
</script>
</head>
<body>
<h1>Netty-socketio Demo Chat</h1>
<br/>
<div id="console" class="well">
</div>
<form class="well form-inline" onsubmit="return false;">
<input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/>
<button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
</form>
</body>
</html>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,139 @@
<!DOCTYPE html>
<html>
<head>
<title>Demo Chat</title>
<link href="bootstrap.css" rel="stylesheet">
<style>
body {
padding:20px;
}
.console {
height: 400px;
overflow: auto;
}
.username-msg {color:orange;}
.connect-msg {color:green;}
.disconnect-msg {color:red;}
.send-msg {color:#888}
</style>
<script src="js/socket.io/socket.io.js"></script>
<script src="js/moment.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var userName1 = 'user1_' + Math.floor((Math.random()*1000)+1);
var userName2 = 'user2_' + Math.floor((Math.random()*1000)+1);
var chat1Socket = io.connect('http://localhost:9092/chat1');
var chat2Socket = io.connect('http://localhost:9092/chat2');
function connectHandler(parentId) {
return function() {
output('<span class="connect-msg">Client has connected to the server!</span>', parentId);
}
}
function messageHandler(parentId) {
return function(data) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message, parentId);
}
}
function disconnectHandler(parentId) {
return function() {
output('<span class="disconnect-msg">The client has disconnected!</span>', parentId);
}
}
function sendMessageHandler(parentId, userName, chatSocket) {
var message = $(parentId + ' .msg').val();
$(parentId + ' .msg').val('');
var jsonObject = {'@class': 'com.corundumstudio.socketio.demo.ChatObject',
userName: userName,
message: message};
chatSocket.json.send(jsonObject);
}
chat1Socket.on('connect', connectHandler('#chat1'));
chat2Socket.on('connect', connectHandler('#chat2'));
chat1Socket.on('message', messageHandler('#chat1'));
chat2Socket.on('message', messageHandler('#chat2'));
chat1Socket.on('disconnect', disconnectHandler('#chat1'));
chat2Socket.on('disconnect', disconnectHandler('#chat2'));
function sendDisconnect1() {
chat1Socket.disconnect();
}
function sendDisconnect2() {
chat2Socket.disconnect();
}
function sendMessage1() {
sendMessageHandler('#chat1', userName1, chat1Socket);
}
function sendMessage2() {
sendMessageHandler('#chat2', userName2, chat2Socket);
}
function output(message, parentId) {
var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div>");
$(parentId + ' .console').prepend(element);
}
$(document).keydown(function(e){
if(e.keyCode == 13) {
$('#send').click();
}
});
</script>
</head>
<body>
<h1>Namespaces demo chat</h1>
<br/>
<div id="chat1" style="width: 49%; float: left;">
<h4>chat1</h4>
<div class="console well">
</div>
<form class="well form-inline" onsubmit="return false;">
<input class="msg input-xlarge" type="text" placeholder="Type something..."/>
<button type="button" onClick="sendMessage1()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect1()" class="btn">Disconnect</button>
</form>
</div>
<div id="chat2" style="width: 49%; float: right;" >
<h4>chat2</h4>
<div class="console well">
</div>
<form class="well form-inline" onsubmit="return false;">
<input class="msg input-xlarge" type="text" placeholder="Type something..."/>
<button type="button" onClick="sendMessage2()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect2()" class="btn">Disconnect</button>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,90 @@
<!DOCTYPE html>
<html>
<head>
<title>Demo Chat</title>
<link href="bootstrap.css" rel="stylesheet">
<style>
body {
padding:20px;
}
#console {
height: 400px;
overflow: auto;
}
.username-msg {color:orange;}
.connect-msg {color:green;}
.disconnect-msg {color:red;}
.send-msg {color:#888}
</style>
<script src="js/socket.io/socket.io.js"></script>
<script src="js/moment.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var userName = 'user' + Math.floor((Math.random()*1000)+1);
var socket = io.connect('https://localhost:10443');
socket.on('connect', function() {
output('<span class="connect-msg">Client has connected to the server!</span>');
});
socket.on('chatevent', function(data) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
});
socket.on('disconnect', function() {
output('<span class="disconnect-msg">The client has disconnected!</span>');
});
function sendDisconnect() {
socket.disconnect();
}
function sendMessage() {
var message = $('#msg').val();
$('#msg').val('');
socket.emit('chatevent', {userName: userName, message: message});
}
function output(message) {
var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div>");
$('#console').prepend(element);
}
$(document).keydown(function(e){
if(e.keyCode == 13) {
$('#send').click();
}
});
</script>
</head>
<body>
<h1>Netty-socketio Demo Chat</h1>
<br/>
<div id="console" class="well">
</div>
<form class="well form-inline" onsubmit="return false;">
<input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/>
<button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
</form>
</body>
</html>

View File

@ -0,0 +1,59 @@
package com.zheng.message.server;
import com.corundumstudio.socketio.AckCallback;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.VoidAckCallback;
import com.corundumstudio.socketio.listener.DataListener;
public class AckChatLauncher {
public static void main(String[] args) throws InterruptedException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
final SocketIOServer server = new SocketIOServer(config);
server.addEventListener("ackevent1", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(final SocketIOClient client, ChatObject data, final AckRequest ackRequest) {
// check is ack requested by client,
// but it's not required check
if (ackRequest.isAckRequested()) {
// send ack response with data to client
ackRequest.sendAckData("client message was delivered to server!", "yeah!");
}
// send message back to client with ack callback WITH data
ChatObject ackChatObjectData = new ChatObject(data.getUserName(), "message with ack data");
client.sendEvent("ackevent2", new AckCallback<String>(String.class) {
@Override
public void onSuccess(String result) {
System.out.println("ack from client: " + client.getSessionId() + " data: " + result);
}
}, ackChatObjectData);
ChatObject ackChatObjectData1 = new ChatObject(data.getUserName(), "message with void ack");
client.sendEvent("ackevent3", new VoidAckCallback() {
@Override
protected void onSuccess() {
System.out.println("void ack from: " + client.getSessionId());
}
}, ackChatObjectData1);
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}

View File

@ -0,0 +1,38 @@
package com.zheng.message.server;
import java.io.UnsupportedEncodingException;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.Transport;
import com.corundumstudio.socketio.listener.DataListener;
public class BinaryEventLauncher {
public static void main(String[] args) throws InterruptedException, UnsupportedEncodingException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
config.setMaxFramePayloadLength(1024 * 1024);
config.setMaxHttpContentLength(1024 * 1024);
final SocketIOServer server = new SocketIOServer(config);
server.addEventListener("msg", byte[].class, new DataListener<byte[]>() {
@Override
public void onData(SocketIOClient client, byte[] data, AckRequest ackRequest) {
client.sendEvent("msg", data);
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}

View File

@ -0,0 +1,30 @@
package com.zheng.message.server;
import com.corundumstudio.socketio.listener.*;
import com.corundumstudio.socketio.*;
public class ChatLauncher {
public static void main(String[] args) throws InterruptedException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
final SocketIOServer server = new SocketIOServer(config);
server.addEventListener("chatevent", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
// broadcast messages to all clients
server.getBroadcastOperations().sendEvent("chatevent", data);
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}

View File

@ -0,0 +1,31 @@
package com.zheng.message.server;
public class ChatObject {
private String userName;
private String message;
public ChatObject() {
}
public ChatObject(String userName, String message) {
super();
this.userName = userName;
this.message = message;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,32 @@
package com.zheng.message.server;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.DataListener;
public class EventChatLauncher {
public static void main(String[] args) throws InterruptedException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
final SocketIOServer server = new SocketIOServer(config);
server.addEventListener("chatevent", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
server.getBroadcastOperations().sendEvent("chatevent", data);
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}

View File

@ -0,0 +1,40 @@
package com.zheng.message.server;
import com.corundumstudio.socketio.listener.*;
import com.corundumstudio.socketio.*;
public class NamespaceChatLauncher {
public static void main(String[] args) throws InterruptedException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
final SocketIOServer server = new SocketIOServer(config);
final SocketIONamespace chat1namespace = server.addNamespace("/chat1");
chat1namespace.addEventListener("message", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
// broadcast messages to all clients
chat1namespace.getBroadcastOperations().sendEvent("message", data);
}
});
final SocketIONamespace chat2namespace = server.addNamespace("/chat2");
chat2namespace.addEventListener("message", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
// broadcast messages to all clients
chat2namespace.getBroadcastOperations().sendEvent("message", data);
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}

View File

@ -0,0 +1,38 @@
package com.zheng.message.server;
import java.io.InputStream;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.DataListener;
public class SslChatLauncher {
public static void main(String[] args) throws InterruptedException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(10443);
config.setKeyStorePassword("test1234");
InputStream stream = SslChatLauncher.class.getResourceAsStream("/keystore.jks");
config.setKeyStore(stream);
final SocketIOServer server = new SocketIOServer(config);
server.addEventListener("chatevent", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
server.getBroadcastOperations().sendEvent("chatevent", data);
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}