Skip to content

Commit

Permalink
✨ spring-boot-demo-websocket-socketio 后端完成
Browse files Browse the repository at this point in the history
  • Loading branch information
xkcoding committed Dec 18, 2018
1 parent 9cb7332 commit 4bfb4f1
Show file tree
Hide file tree
Showing 12 changed files with 559 additions and 2 deletions.
19 changes: 18 additions & 1 deletion spring-boot-demo-websocket-socketio/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<netty-socketio.version>1.7.12</netty-socketio.version>
<netty-socketio.version>1.7.16</netty-socketio.version>
</properties>

<dependencies>
Expand All @@ -35,11 +35,28 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.xkcoding.websocket.socketio.config;

import cn.hutool.core.collection.CollUtil;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
* <p>
* 模拟数据库
* </p>
*
* @package: com.xkcoding.websocket.socketio.config
* @description: 模拟数据库
* @author: yangkai.shen
* @date: Created in 2018-12-18 19:12
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Component
public class DbTemplate {
/**
* 模拟数据库存储 user_id <-> session_id 的关系
*/
public static final ConcurrentHashMap<String, UUID> DB = new ConcurrentHashMap<>();

/**
* 获取所有SessionId
*
* @return SessionId列表
*/
public List<UUID> findAll() {
return CollUtil.newArrayList(DB.values());
}

/**
* 根据UserId查询SessionId
*
* @param userId 用户id
* @return SessionId
*/
public Optional<UUID> findByUserId(String userId) {
return Optional.ofNullable(DB.get(userId));
}

/**
* 保存/更新 user_id <-> session_id 的关系
*
* @param userId 用户id
* @param sessionId SessionId
*/
public void save(String userId, UUID sessionId) {
DB.put(userId, sessionId);
}

/**
* 删除 user_id <-> session_id 的关系
*
* @param userId 用户id
*/
public void deleteByUserId(String userId) {
DB.remove(userId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.xkcoding.websocket.socketio.config;

/**
* <p>
* 事件常量
* </p>
*
* @package: com.xkcoding.websocket.socketio.config
* @description: 事件常量
* @author: yangkai.shen
* @date: Created in 2018-12-18 19:36
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
public interface Event {
/**
* 聊天事件
*/
String CHAT = "chat" ;

/**
* 收到消息
*/
String CHAT_RECEIVED = "chat_received" ;

/**
* 拒收消息
*/
String CHAT_REFUSED = "chat_refused" ;

/**
* 广播消息
*/
String BROADCAST = "broadcast" ;

/**
* 群聊
*/
String GROUP = "group" ;

/**
* 加入群聊
*/
String JOIN = "join" ;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.xkcoding.websocket.socketio.config;

import cn.hutool.core.util.StrUtil;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* <p>
* 服务器配置
* </p>
*
* @package: com.xkcoding.websocket.socketio.config
* @description: 服务器配置
* @author: yangkai.shen
* @date: Created in 2018-12-18 16:42
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Configuration
@EnableConfigurationProperties({WsConfig.class})
public class ServerConfig {

@Bean
public SocketIOServer server(WsConfig wsConfig) {
com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
config.setHostname(wsConfig.getHost());
config.setPort(wsConfig.getPort());

//这个listener可以用来进行身份验证
config.setAuthorizationListener(data -> {
// http://localhost:8081?token=xxxxxxx
// 例如果使用上面的链接进行connect,可以使用如下代码获取用户密码信息,本文不做身份验证
String token = data.getSingleUrlParam("token");
// 校验token的合法性,实际业务需要校验token是否过期等等,参考 spring-boot-demo-rbac-security 里的 JwtUtil
// 如果认证不通过会返回一个 Socket.EVENT_CONNECT_ERROR 事件
return StrUtil.isNotBlank(token);
});

return new SocketIOServer(config);
}

/**
* Spring 扫描自定义注解
*/
@Bean
public SpringAnnotationScanner springAnnotationScanner(SocketIOServer server) {
return new SpringAnnotationScanner(server);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.xkcoding.websocket.socketio.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* <p>
* WebSocket配置类
* </p>
*
* @package: com.xkcoding.websocket.socketio.config
* @description: WebSocket配置类
* @author: yangkai.shen
* @date: Created in 2018-12-18 16:41
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@ConfigurationProperties(prefix = "ws.server")
@Data
public class WsConfig {
/**
* 端口号
*/
private Integer port;

/**
* host
*/
private String host;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.xkcoding.websocket.socketio.controller;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.xkcoding.websocket.socketio.handler.MessageEventHandler;
import com.xkcoding.websocket.socketio.payload.BroadcastMessageRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;

/**
* <p>
* 消息发送Controller
* </p>
*
* @package: com.xkcoding.websocket.socketio.controller
* @description: 消息发送Controller
* @author: yangkai.shen
* @date: Created in 2018-12-18 19:50
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@RestController
@RequestMapping("/send")
@Slf4j
public class MessageController {
@Autowired
private MessageEventHandler messageHandler;

@PostMapping("/broadcast")
public Dict broadcast(BroadcastMessageRequest message) {
if (isBlank(message)) {
return Dict.create().set("flag", false).set("code", 400).set("message", "参数为空");
}
messageHandler.sendToBroadcast(message);
return Dict.create().set("flag", true).set("code", 200).set("message", "发送成功");
}

/**
* 判断Bean是否为空对象或者空白字符串,空对象表示本身为<code>null</code>或者所有属性都为<code>null</code>
*
* @param bean Bean对象
* @return 是否为空,<code>true</code> - 空 / <code>false</code> - 非空
* @since 4.1.10
*/
private boolean isBlank(Object bean) {
if (null != bean) {
for (Field field : ReflectUtil.getFields(bean.getClass())) {
Object fieldValue = ReflectUtil.getFieldValue(bean, field);
if (null != fieldValue) {
if (fieldValue instanceof String && StrUtil.isNotBlank((String) fieldValue)) {
return false;
} else if (!(fieldValue instanceof String)) {
return false;
}
}
}
}
return true;
}

}
Loading

0 comments on commit 4bfb4f1

Please sign in to comment.