socketio依賴:
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.17</version>
</dependency>
主程序:
@SpringBootApplication
@Configuration
public class MainApplication extends SpringBootServletInitializer {
@Bean
public SocketIOServer socketIOServer(){
com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
// 注意:如果本地測試,可以使用localhost;如果阿里雲服務器,則需指定 “內網ip”
config.setHostname("localhost");
config.setPort(9090);
// 設置最大的webSocket幀內容長度限制
config.setMaxFramePayloadLength(1024 * 1024);
// 設置最大http內容長度限制
config.setMaxHttpContentLength(1024 * 1024);
return new SocketIOServer(config);
}
@Bean
public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketIOServer){
return new SpringAnnotationScanner(socketIOServer);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MainApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
通信包裝實體:
@Data
public class SocketIoMsg {
private String type;
private String msg;
}
自定義socketio啓動命令,CommandLineRunner在springboot啓動時,可以預先執行一些代碼或初始化數據:
@Component
@Order(1)
public class SocketioCommandLineRunner implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(SocketioCommandLineRunner.class);
private SocketIOServer socketIOServer;
@Autowired
public SocketioCommandLineRunner(SocketIOServer socketIOServer){
this.socketIOServer = socketIOServer;
}
@Override
public void run(String... strings) throws Exception {
socketIOServer.start();
logger.info("socketio server started");
}
}
消息事件處理類:
@Component
public class SocketioMsgEventHandler {
private Logger logger = LoggerFactory.getLogger(SocketioMsgEventHandler.class);
public static SocketIOServer socketIOServer;
@Autowired
public SocketioMsgEventHandler(SocketIOServer socketIOServer){
this.socketIOServer = socketIOServer;
}
@Autowired
private PlatNoticeService platNoticeService;
public static List<UUID> clientList = new ArrayList<>();
@OnConnect
@SuppressWarnings("unchecked")
public void onConnect(SocketIOClient client){
clientList.add(client.getSessionId());
// 發送消息
Response response = platNoticeService.getPlatShowList();
if(response.getStatus().isSuccess()){
List<PlatNoticeModel> noticeModelList = (List<PlatNoticeModel>) response.getData();
for(PlatNoticeModel noticeModel : noticeModelList){
client.sendEvent(PlatNoticeTypeEnum.noticeStart.toString(), noticeModel.getContent());
}
}
logger.info("新的連接:" + client.getSessionId());
}
@OnDisconnect
public void onDisconnect(SocketIOClient client){
clientList.remove(client.getSessionId());
logger.info("連接斷開:" + client.getSessionId());
}
@OnEvent(value = "msgEvent")
public void msgEvent(SocketIOClient client, AckRequest ackReq, SocketIoMsg msg){
logger.info("發來消息:" + client.getSessionId() + "," + msg.getMsg());
socketIOServer.getClient(client.getSessionId()).sendEvent("msgEvent", "success");
}
public static void sendMsg(List<UUID> msgClientList, String type, String msg){
List<UUID> idList = new ArrayList<>();
if(CollectionUtils.isEmpty(msgClientList)){
idList.addAll(clientList);
}else{
idList.addAll(msgClientList);
}
for(UUID uuid : idList){
if(uuid != null){
SocketIOClient client = socketIOServer.getClient(uuid);
if(client != null){
client.sendEvent(type, msg);
}
}
}
}
}
注意事項:
- 如果是在本地測試,config.setHostname(“localhost”); 可以直接指定localhost
- 但是在阿里雲服務器上,一定要指定 內網ip,然後客戶端調用時指定外網ip
- 在阿里雲控制檯,去設置安全組,將socketio端口開放
錯誤:
java.net.BindException: Cannot assign requested address: bind
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
如果出現以上錯誤,請檢查hostname的設置,本機就是localhost,雲服務器就用服務器的ip,例如阿里雲使用內網設置