1、pom
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.18</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.0</version>
</dependency>
2、启动
package com.corundumstudio.socketio.demo;
import com.corundumstudio.socketio.listener.*;
import com.corundumstudio.socketio.*;
import com.corundumstudio.socketio.store.RedissonStoreFactory;
import com.corundumstudio.socketio.store.StoreFactory;
import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.Calendar;
import java.util.UUID;
public class ChatLauncher {
public static void main(String[] args) throws InterruptedException {
Config redis = new Config();
redis.useSingleServer().setAddress("redis://192.168.32.136:26379").setPassword("123456");
final RedissonClient redisson = Redisson.create(redis);
Configuration config = new Configuration();
config.setPort(9092);
StoreFactory storeFactory = new RedissonStoreFactory(redisson);
//session存储在redis
config.setStoreFactory(storeFactory);
final SocketIOServer server = new SocketIOServer(config);
server.addConnectListener(new ConnectListener() {
@Override
public void onConnect(SocketIOClient socketIOClient) {
//用户连接
//id为连用户id
String userId = socketIOClient.getHandshakeData().getSingleUrlParam("id");
//保存uuid key 用户id value SocketIOClient的UUID
RBucket<UUID> id = redisson.getBucket(userId);
UUID uuid = socketIOClient.getSessionId();
id.set(uuid);
//保存uuid和用户id的映射 key为uuid value 为用户id
RBucket<String> userIdBucket = redisson.getBucket(uuid.toString());
userIdBucket.set(userId);
}
});
server.addDisconnectListener(new DisconnectListener() {
@Override
public void onDisconnect(SocketIOClient socketIOClient) {
//用户断开连接连接 清除缓存保存的用户信息
String extNum = socketIOClient.getHandshakeData().getSingleUrlParam("id");
RBucket<UUID> id = redisson.getBucket(extNum);
String uuid = id.get().toString();
RBucket<String> userId = redisson.getBucket(uuid);
userId.delete();
id.delete();
}
});
server.addEventListener("chatevent", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
//userName 把消息发给谁
String userName = data.getUserName();
// from是谁发的消息
String from = (String) redisson.getBucket(client.getSessionId().toString()).get();
RBucket<UUID> id = redisson.getBucket(userName);
//获取接收消息的SocketIOClient
SocketIOClient to = server.getClient(id.get());
ChatObject chatObject = new ChatObject();
chatObject.setMessage(data.getMessage());
chatObject.setUserName(from);
//发送消息 给消息接收者
to.sendEvent("chatevent", chatObject);
}
});
server.addEventListener("createRoom", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
//创建群聊 生成群名称
String roomName = "room:" + client.getHandshakeData().getSingleUrlParam("id");
client.joinRoom(roomName);
}
});
server.addEventListener("joinRoom", ChatObject.class, new DataListener<ChatObject>() {
@Override
public void onData(SocketIOClient client, ChatObject data, AckRequest ackRequest) {
//群名称
String roomName = data.getRoomName();
client.joinRoom(roomName);
// from是谁发的消息
String from = (String) redisson.getBucket(client.getSessionId().toString()).get();
ChatObject chatObject = new ChatObject();
chatObject.setMessage("加入群聊:"+roomName);
chatObject.setUserName(from);
// server.getRoomOperations(roomName).sendEvent("joinRoom", chatObject);
server.getRoomOperations(roomName).sendEvent("joinRoom", chatObject, client, new BroadcastAckCallback(Boolean.class));
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}
3、消息实体
package com.corundumstudio.socketio.demo;
import java.io.Serializable;
public class ChatObject implements Serializable {
private String userName;
private String message;
private String roomName;
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;
}
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
}
4、客户端1
<!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>
//发送消息给用户id是2的
var userName = 2;
//用户id 是1的连接
var socket = io.connect('http://localhost:9092?id=1');
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>');
});
socket.on('joinRoom', function(data) {
output('<span class="username-msg">' + data.userName + ':</span> ' + data.message);
});
function sendDisconnect() {
socket.disconnect();
}
function sendMessage() {
var message = $('#msg').val();
$('#msg').val('');
var jsonObject = {userName: userName,
message: message};
socket.emit('chatevent', jsonObject);
}
function createRoom() {
socket.emit('createRoom', null);
}
function output(message) {
var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div>");
$('#console').prepend(element);
}
function joinRoom() {
var roomName = $('#roomName').val();
$('#roomName').val('');
var jsonObject = {roomName: roomName,
message: ''};
socket.emit('joinRoom', jsonObject);
}
$(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..."/>
<input id="roomName" class="input-xlarge" type="text" placeholder="room name"/>
<button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
<button type="button" onClick="createRoom()" class="btn">createRoom</button>
<button type="button" onClick="joinRoom()" class="btn">joinRoom</button>
</form>
</body>
</html>
5、客户端2
<!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>
//发送消息给用户id是1的
var userName = 1;
//用户id 是2的连接
var socket = io.connect('ws://localhost:9092?id=2');
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('joinRoom', 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('');
var jsonObject = {userName: userName,
message: message};
socket.emit('chatevent', jsonObject);
}
function createRoom() {
socket.emit('createRoom', null);
}
function joinRoom() {
var roomName = $('#roomName').val();
$('#roomName').val('');
var jsonObject = {roomName: roomName,
message: ''};
socket.emit('joinRoom', 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>
</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..."/>
<input id="roomName" class="input-xlarge" type="text" placeholder="room name"/>
<button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>
<button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
<button type="button" onClick="createRoom()" class="btn">createRoom</button>
<button type="button" onClick="joinRoom(roomName)" class="btn">joinRoom</button>
</form>
</body>
</html>