SpringBoot实战之netty-socketio实现简单聊天室(给指定用户推送消息)
网上好多例子都是群发的,本文实现一对一的发送,给指定客户端进行消息推送
成都创新互联于2013年成立,先为昔阳等服务建站,昔阳等地企业,进行企业商务咨询服务。为昔阳企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
1、本文使用到netty-socketio开源库,以及MySQL,所以首先在pom.xml中添加相应的依赖库
com.corundumstudio.socketio netty-socketio 1.7.11 org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java
2、修改application.properties, 添加端口及主机数据库连接等相关配置,
wss.server.port=8081 wss.server.host=localhost spring.datasource.url = jdbc:mysql://127.0.0.1:3306/springlearn spring.datasource.username = root spring.datasource.password = root spring.datasource.driverClassName = com.mysql.jdbc.Driver # Specify the DBMS spring.jpa.database = MYSQL # Show or not log for each sql query spring.jpa.show-sql = true # Hibernate ddl auto (create, create-drop, update) spring.jpa.hibernate.ddl-auto = update # Naming strategy spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy # stripped before adding them to the entity manager) spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
3、修改Application文件,添加nettysocket的相关配置信息
package com.xiaofangtech.sunt; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import com.corundumstudio.socketio.AuthorizationListener; import com.corundumstudio.socketio.Configuration; import com.corundumstudio.socketio.HandshakeData; import com.corundumstudio.socketio.SocketIOServer; import com.corundumstudio.socketio.annotation.SpringAnnotationScanner; @SpringBootApplication public class NettySocketSpringApplication { @Value("${wss.server.host}") private String host; @Value("${wss.server.port}") private Integer port; @Bean public SocketIOServer socketIOServer() { Configuration config = new Configuration(); config.setHostname(host); config.setPort(port); //该处可以用来进行身份验证 config.setAuthorizationListener(new AuthorizationListener() { @Override public boolean isAuthorized(HandshakeData data) { //http://localhost:8081?username=test&password=test //例如果使用上面的链接进行connect,可以使用如下代码获取用户密码信息,本文不做身份验证 // String username = data.getSingleUrlParam("username"); // String password = data.getSingleUrlParam("password"); return true; } }); final SocketIOServer server = new SocketIOServer(config); return server; } @Bean public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) { return new SpringAnnotationScanner(socketServer); } public static void main(String[] args) { SpringApplication.run(NettySocketSpringApplication.class, args); } }
4、添加消息结构类MessageInfo.java
package com.xiaofangtech.sunt.message; public class MessageInfo { //源客户端id private String sourceClientId; //目标客户端id private String targetClientId; //消息类型 private String msgType; //消息内容 private String msgContent; public String getSourceClientId() { return sourceClientId; } public void setSourceClientId(String sourceClientId) { this.sourceClientId = sourceClientId; } public String getTargetClientId() { return targetClientId; } public void setTargetClientId(String targetClientId) { this.targetClientId = targetClientId; } public String getMsgType() { return msgType; } public void setMsgType(String msgType) { this.msgType = msgType; } public String getMsgContent() { return msgContent; } public void setMsgContent(String msgContent) { this.msgContent = msgContent; } }
5、添加客户端信息,用来存放客户端的sessionid
package com.xiaofangtech.sunt.bean; import java.util.Date; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.NotNull; @Entity @Table(name="t_clientinfo") public class ClientInfo { @Id @NotNull private String clientid; private Short connected; private Long mostsignbits; private Long leastsignbits; private Date lastconnecteddate; public String getClientid() { return clientid; } public void setClientid(String clientid) { this.clientid = clientid; } public Short getConnected() { return connected; } public void setConnected(Short connected) { this.connected = connected; } public Long getMostsignbits() { return mostsignbits; } public void setMostsignbits(Long mostsignbits) { this.mostsignbits = mostsignbits; } public Long getLeastsignbits() { return leastsignbits; } public void setLeastsignbits(Long leastsignbits) { this.leastsignbits = leastsignbits; } public Date getLastconnecteddate() { return lastconnecteddate; } public void setLastconnecteddate(Date lastconnecteddate) { this.lastconnecteddate = lastconnecteddate; } }
6、添加查询数据库接口ClientInfoRepository.java
package com.xiaofangtech.sunt.repository; import org.springframework.data.repository.CrudRepository; import com.xiaofangtech.sunt.bean.ClientInfo; public interface ClientInfoRepository extends CrudRepository{ ClientInfo findClientByclientid(String clientId); }
7、添加消息处理类MessageEventHandler.Java
package com.xiaofangtech.sunt.message; import java.util.Date; import java.util.UUID; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.corundumstudio.socketio.AckRequest; import com.corundumstudio.socketio.SocketIOClient; import com.corundumstudio.socketio.SocketIOServer; import com.corundumstudio.socketio.annotation.OnConnect; import com.corundumstudio.socketio.annotation.OnDisconnect; import com.corundumstudio.socketio.annotation.OnEvent; import com.xiaofangtech.sunt.bean.ClientInfo; import com.xiaofangtech.sunt.repository.ClientInfoRepository; @Component public class MessageEventHandler { private final SocketIOServer server; @Autowired private ClientInfoRepository clientInfoRepository; @Autowired public MessageEventHandler(SocketIOServer server) { this.server = server; } //添加connect事件,当客户端发起连接时调用,本文中将clientid与sessionid存入数据库 //方便后面发送消息时查找到对应的目标client, @OnConnect public void onConnect(SocketIOClient client) { String clientId = client.getHandshakeData().getSingleUrlParam("clientid"); ClientInfo clientInfo = clientInfoRepository.findClientByclientid(clientId); if (clientInfo != null) { Date nowTime = new Date(System.currentTimeMillis()); clientInfo.setConnected((short)1); clientInfo.setMostsignbits(client.getSessionId().getMostSignificantBits()); clientInfo.setLeastsignbits(client.getSessionId().getLeastSignificantBits()); clientInfo.setLastconnecteddate(nowTime); clientInfoRepository.save(clientInfo); } } //添加@OnDisconnect事件,客户端断开连接时调用,刷新客户端信息 @OnDisconnect public void onDisconnect(SocketIOClient client) { String clientId = client.getHandshakeData().getSingleUrlParam("clientid"); ClientInfo clientInfo = clientInfoRepository.findClientByclientid(clientId); if (clientInfo != null) { clientInfo.setConnected((short)0); clientInfo.setMostsignbits(null); clientInfo.setLeastsignbits(null); clientInfoRepository.save(clientInfo); } } //消息接收入口,当接收到消息后,查找发送目标客户端,并且向该客户端发送消息,且给自己发送消息 @OnEvent(value = "messageevent") public void onEvent(SocketIOClient client, AckRequest request, MessageInfo data) { String targetClientId = data.getTargetClientId(); ClientInfo clientInfo = clientInfoRepository.findClientByclientid(targetClientId); if (clientInfo != null && clientInfo.getConnected() != 0) { UUID uuid = new UUID(clientInfo.getMostsignbits(), clientInfo.getLeastsignbits()); System.out.println(uuid.toString()); MessageInfo sendData = new MessageInfo(); sendData.setSourceClientId(data.getSourceClientId()); sendData.setTargetClientId(data.getTargetClientId()); sendData.setMsgType("chat"); sendData.setMsgContent(data.getMsgContent()); client.sendEvent("messageevent", sendData); server.getClient(uuid).sendEvent("messageevent", sendData); } } }
8、添加ServerRunner.java
package com.xiaofangtech.sunt.message; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.corundumstudio.socketio.SocketIOServer; @Component public class ServerRunner implements CommandLineRunner { private final SocketIOServer server; @Autowired public ServerRunner(SocketIOServer server) { this.server = server; } @Override public void run(String... args) throws Exception { server.start(); } }
9、工程结构
10、运行测试
1) 添加基础数据,数据库中预置3个客户端testclient1,testclient2,testclient3
2) 创建客户端文件index.html,index2.html,index3.html分别代表testclient1 testclient2 testclient3三个用户
本文直接修改的https://github.com/mrniko/netty-socketio-demo/tree/master/client 中的index.html文件
其中clientid为发送者id, targetclientid为目标方id,本文简单的将发送方和接收方写死在html文件中
使用 以下代码进行连接
io.connect('http://localhost:8081?clientid='+clientid);
index.html 文件内容如下
Demo Chat Netty-socketio Demo Chat
3、本例测试时
testclient1 发送消息给 testclient2
testclient2 发送消息给 testclient1
testclient3发送消息给testclient1
运行结果如下
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。
文章名称:SpringBoot实战之netty-socketio实现简单聊天室(给指定用户推送消息)
文章位置:http://myzitong.com/article/geecgj.html