Netty-SocketIO 网址:
https:///mrniko/netty-socketio。
Netty-SocketIO是一个开源的、基于Netty的、Java版的即时消息推送项目。Socket.IO除了支持WebSocket通讯协议外,还支持许多种轮询(Polling)机制以及其它实时通信方式,并封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。Socket.IO实现的Polling通信机制包括Adobe Flash Socket、AJAX长轮询、AJAX multipart streaming、持久Iframe、JSONP轮询等。Socket.IO能够根据浏览器对通讯机制的支持情况自动地选择最佳的方式来实现网络实时应用。
项目文件构架
源码
ChatListener.java
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.DataListener;
public class ChatListener implements DataListener<Msg> {
SocketIOServer server;
public void setServer(SocketIOServer server) {
this.server = server;
}
public void onData(SocketIOClient socketIoClient, Msg msg,
AckRequest askSender) throws Exception {
// chatevent为 事件的名称, msg为发送的内容
this.server.getBroadcastOperations().sendEvent("chatevent", msg);
}
}
Msg.java
import java.io.Serializable;
public class Msg implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6519304261259719883L;
private String userId;
private String userName;
private String receiveUserId;
private String content;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getReceiveUserId() {
return receiveUserId;
}
public void setReceiveUserId(String receiveUserId) {
this.receiveUserId = receiveUserId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Msg(String userId, String userName, String receiveUserId,
String content) {
super();
this.userId = userId;
this.userName = userName;
this.receiveUserId = receiveUserId;
this.content = content;
}
public Msg() {
super();
}
}
MsgServer.java
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
public class MsgServer {
static Map<String,SocketIOClient> clientsMap = new HashMap<String, SocketIOClient>();
public static void main(String[] args) throws InterruptedException {
ServerContext.init();
Configuration config = new Configuration();
config.setHostname(ServerContext.serverIp);
config.setPort(ServerContext.port);
config.setMaxFramePayloadLength(1024 * 1024);
config.setMaxHttpContentLength(1024 * 1024);
SocketIOServer server = new SocketIOServer(config);
ChatListener listner = new ChatListener();
listner.setServer(server);
server.addEventListener("chatevent", Msg.class, listner);
server.addConnectListener(new ConnectListener(){
public void onConnect(SocketIOClient client) {
String sa = client.getRemoteAddress().toString();
String clientIp = sa.substring(1,sa.indexOf(":"));//获取客户端ip
System.out.println(clientIp+"-------------------------"+"客户端已连接");
Map<?, ?> params = client.getHandshakeData().getUrlParams();
//获取客户端连接的uuid参数
Object object = params.get("myparam");
String test = "";
if(object != null){
test = ((List<String>)object).get(0);
//将uuid和连接客户端对象进行绑定
clientsMap.put(test,client);
}
//给客户端发送消息
client.sendEvent("connect_msg",clientIp+"客户端你好,我是服务端");
}
});
// 启动socket.io服务
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
}
ServerContext.java
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class ServerContext {
public static String serverIp;
public static int port ;
public static void init() {
Properties properties = new Properties();
try {
properties.load(ServerContext.class.getClassLoader()
.getResourceAsStream("info.properties"));// new
// FileInputStream(new
// File("system.properties")
serverIp = properties.getProperty("server.ip");
port = Integer.valueOf(properties.getProperty("server.port"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
log4j.properties
log4j.rootLogger=INFO,stdout,file
## for stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d] %m - [%c] %n
## for file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=../logs/socketio.log
log4j.appender.file.MaxFileSize=100MB
log4j.appender.file.Append = true
log4j.appender.file.MaxBackupIndex=100
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%d] %m - [%c] %p %n
info.properties
server.ip=192.10.200.203
server.port=8002
pom.xml
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:///POM/4.0.0 http:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.whr.test.alisocketio</groupId>
<artifactId>com.whr.test.alisocketio</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build/>
<properties>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.12</version>
</dependency>
<!-- 日志文件管理包 -->
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- 格式化对象,方便输出日志 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
</project>
前端代码
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SOCKET.IO DEMO</title>
<base>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/socket.io/1.7.4/socket.io.min.js"></script>
<script src="https://cdn.bootcss.com/ckeditor/4.8.0/ckeditor.js"></script>
<style>
body {padding: 20px;}
#console {height: 450px;overflow: auto;}
.username-msg {color: orange;}
.connect-msg {color: green;}
.disconnect-msg {color: red;}
</style>
</head>
<body>
<h1>测试聊天程序</h1>
<div id="console" class="well"></div>
<form class="well form-inline" onsubmit="return false;">
<input id="name" class="input-xlarge" type="hidden" placeholder="用户名称. . . " />
<textarea id="msg" rows="10" cols="50" placeholder="发送内容. . . "></textarea>
<button type="button" onClick="sendMessage()" class="btn">发送</button>
<button type="button" onClick="sendDisconnect()" class="btn">离线</button>
<button type="button" onClick="reloadThis()" class="btn">上线</button>
</form>
</body>
<script type="text/javascript">
var editor = CKEDITOR.replace('msg');
editor.on("instanceReady", function () {
this.document.on("keydown", function () {
var event = window.frames[0].event;
if (event.ctrlKey && event.keyCode == 13) { // enter 键
//要做的事情
sendMessage();
}
});
});
var socket;
connect();
function connect() {
socket = io.connect('ws://192.10.200.203:8002?myparam=testabc');
$("#name").val("访客" + parseInt(Math.random() * 100 + 1, 10));
socket.on('connect', function () {
console.log("连接成功");
serverOutput('<span class="connect-msg">欢迎光临!</span>');
socket.emit('chatevent', {
userId: 1,
userName: $("#name").val(),
receiveUserId: 2,
content: "已上线!"
});
});
socket.on('chatevent', function (data) {
output('<span class="username-msg">' + '<img src="images/head.jpg" height="32" width="32"/>' +
data.userName + ' : </span>' +
data.content);
});
socket.on('disconnect', function () {
serverOutput('<span class="disconnect-msg">' + $("#name").val() + '已下线! </span>');
});
socket.on('connect_msg',function(data){
console.log('server reply connect:',data);
});
}
function reloadThis() {
socket.disconnect();
connect();
console.log(socket);
}
function sendDisconnect() {
socket.emit('chatevent', {
userId: 1,
userName: $("#name").val(),
receiveUserId: 2,
content: "已下线!"
});
socket.disconnect();
}
function sendMessage() {
var userName = $("#name").val()
var message = editor.getData();
$('#msg').val('');
socket.emit('chatevent', {
userId: 1,
userName: userName,
receiveUserId: 2,
content: message
});
}
function output(message) {
var currentTime = "<span class='time' >" + new Date() + "</span>";
var element = $("<div>" + " " + message + "</div>");
$('#console').prepend(element);
}
function serverOutput(message) {
var element = $("<div>" + message + "</div>");
$('#console').prepend(element);
}
document.onkeydown = function (event) {
var e = event || window.event || arguments.callee.caller.arguments[0];
if (event.ctrlKey && event.keyCode == 13) { // enter 键
sendMessage();
}
};
</script>
</html>
参考文章 :