socket.io数据推送

参考:基于netty-socketio的web推送服务Spring Boot实战之netty-socketio实现简单聊天室(给指定用户推送消息)socket.io 中文文档

socketio简介
Socket.io是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5.

socket.io特点
实时分析:将数据推送到客户端,这些客户端会被表示为实时计数器,图表或日志客户。
实时通信和聊天:只需几行代码便可写成一个Socket.IO的”Hello,World”聊天应用。
二进制流传输:从1.0版本开始,Socket.IO支持任何形式的二进制文件传输,例如:图片,视频,音频等。
文档合并:允许多个用户同时编辑一个文档,并且能够看到每个用户做出的修改。

Demo简介

服务端使用netty-socketio,客户端使用socket.io.js。
本例完全来自上面的链接,这里只是测试效果以及做备忘。本例实现的功能是一个用户向另外一个用法发小消息。

maven中添加依赖

1
2
3
4
5
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.3</version>
</dependency>

服务端SocketServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component
public class ChatServer implements InitializingBean {
@Autowired
private EventListenner eventListenner;
@Override
public void afterPropertiesSet() throws Exception {
Configuration config = new Configuration();
config.setPort(9098);
SocketConfig socketConfig = new SocketConfig();
socketConfig.setReuseAddress(true);
socketConfig.setTcpNoDelay(true);
socketConfig.setSoLinger(0);
config.setSocketConfig(socketConfig);
config.setHostname("localhost");
SocketIOServer server = new SocketIOServer(config);
server.addListeners(eventListenner);
server.start();
System.out.println("启动正常");
}
}

缓存类,缓存客户端连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component("clientCache")
public class SocketIOClientCache {
//String:EventType类型
private Map<String,SocketIOClient> clients=new ConcurrentHashMap<String,SocketIOClient>();
//用户发送消息添加
public void addClient(SocketIOClient client,MsgBean msgBean){
clients.put(msgBean.getFrom(),client);
}
//用户退出时移除
public void remove(MsgBean msgBean) {
clients.remove(msgBean.getFrom());
}
//获取所有
public SocketIOClient getClient(String to) {
return clients.get(to);
}
}

消息发送的类

1
2
3
4
5
6
7
@Service("socketIOResponse")
public class SocketIOResponse {
public void sendEvent(SocketIOClient client, MsgBean bean) {
System.out.println("推送消息");
client.sendEvent("OnMSG", bean);
}
}

事件监听器

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
@Service("eventListenner")
public class EventListenner {
@Resource(name = "clientCache")
private SocketIOClientCache clientCache;
@Resource(name = "socketIOResponse")
private SocketIOResponse socketIOResponse;
@OnConnect
public void onConnect(SocketIOClient client) {
System.out.println("建立连接");
}
@OnEvent("OnMSG")
public void onSync(SocketIOClient client, MsgBean bean) {
System.out.printf("收到消息-from: %s to:%s\n", bean.getFrom(), bean.getTo());
clientCache.addClient(client, bean);
SocketIOClient ioClients = clientCache.getClient(bean.getTo());
System.out.println("clientCache");
if (ioClients == null) {
System.out.println("你发送消息的用户不在线");
return;
}
socketIOResponse.sendEvent(ioClients,bean);
}
@OnDisconnect
public void onDisconnect(SocketIOClient client) {
System.out.println("关闭连接");
}
}

消息bean

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
public class MsgBean { 
private String from;
private String to;
private String content;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "MsgBean [from=" + from + ", to=" + to + ", content=" + content + "]";
}
}

页面

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>socket.io demo</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script type="text/javascript" th:src="@{/js/jquery.js}"></script>
<script type="text/javascript" th:src="@{/js/socket.io.min.js}"></script>
<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>
</head>
<body>
<h1>Netty-socketio chat demo</h1>
<br />
<div id="console" class="well"></div>
<form class="well form-inline" onsubmit="return false;">
<input id="from" class="input-xlarge" type="text" placeholder="from. . . " />
<input id="to" class="input-xlarge" type="text" placeholder="to. . . " />
<input id="content" class="input-xlarge" type="text" placeholder="content. . . " />
<button type="button" onClick="sendMessage()" class="btn">Send</button>
<button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
</form>
</body>
<script type="text/javascript">
var socket = io.connect('http://localhost:9098');
socket.on('connect',function() {
output('<span class="connect-msg">Client has connected to the server!</span>');
});
socket.on('OnMSG', function(data) {
output('<span class="username-msg">' + data.content + ' : </span>');
});
socket.on('disconnect',function() {
output('<span class="disconnect-msg">The client has disconnected! </span>');
});
function sendDisconnect() {
socket.disconnect();
}
function sendMessage() {
var from = $("#from").val();
var to = $("#to").val();
var content = $('#content').val();
socket.emit('OnMSG', {
from : from,
to : to,
content : content
});
}
function output(message) {
console.log(message)
var currentTime = "<span>" + new Date() + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div><br/>");
$('#console').prepend(element);
}
</script>
</html>

说明:工程基于springboot,关于springboot相关的内容并未给出。

测试

浏览器2个标签页分页输入地址,进入到聊天页面。
标签页1

我们假定标签页1用户为admin,标签页2用户为test。
标签页1:admin向test发送1条消息,点击发送,切换到标签页2,发现并没有消息。因为这个时候缓存中没有test,所以没有发送成功。
标签页2:test向admin发送1条消息。

切换到标签页1,可以发现已经接受到test发送的消息

我们F12打开开发人员工具,可以看到多次发送消息并没有产生新的请求。

问题

1.中文乱码
尚未找到解决方案。

netty-socketio:https://github.com/mrniko/netty-socketio
netty-socketio-demo:https://github.com/mrniko/netty-socketio-demo

Donny wechat
欢迎关注我的个人公众号
打赏,是超越赞的一种表达。
Show comments from Gitment