Netty SocketIO是一個 Java 語言版本的 Socket.IO 服務器的實現,基於 Netty 框架開發,使用簡單,功能強大。html
在Spring Boot中包含了對Netty SocketIO的支持,只須要簡單配置便可加入。java
第一步:增長Netty SocketIO的依賴。git
<dependency> <groupId>com.corundumstudio.socketio</groupId> <artifactId>netty-socketio</artifactId> <version>1.7.11</version> </dependency>
第二步:在Application中增長啓動項spring
package com.ukefu; import javax.servlet.MultipartConfigElement; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.ErrorPage; import org.springframework.boot.context.embedded.MultipartConfigFactory; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.http.HttpStatus; import com.corundumstudio.socketio.AuthorizationListener; import com.corundumstudio.socketio.Configuration; import com.corundumstudio.socketio.HandshakeData; import com.corundumstudio.socketio.SocketConfig; import com.corundumstudio.socketio.SocketIOServer; import com.corundumstudio.socketio.annotation.SpringAnnotationScanner; import com.ukefu.core.UKDataContext; @EnableAutoConfiguration @SpringBootApplication @EnableJpaRepositories("com.ukefu.service.repository") public class Application { @Value("${uk.im.server.host}") private String host; @Value("${uk.im.server.port}") private Integer port; @Bean public SocketIOServer socketIOServer() { Configuration config = new Configuration(); // config.setHostname("localhost"); config.setPort(port); config.setSocketConfig(new SocketConfig()); // config.setOrigin("http://im.ukewo.com"); config.setWorkerThreads(100); // config.setStoreFactory(new HazelcastStoreFactory()); config.setAuthorizationListener(new AuthorizationListener() { public boolean isAuthorized(HandshakeData data) { return true; } }); SocketIOServer server = new SocketIOServer(config); server.addNamespace(UKDataContext.NameSpaceEnum.IM.toString()) ; server.addNamespace(UKDataContext.NameSpaceEnum.AGENT.toString()) ; return server; } @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize("50MB"); //KB,MB factory.setMaxRequestSize("100MB"); return factory.createMultipartConfig(); } @Bean public EmbeddedServletContainerCustomizer containerCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { ErrorPage error = new ErrorPage("/error.html"); container.addErrorPages(error); } }; } @Bean public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) { return new SpringAnnotationScanner(socketServer); } public static void main(String[] args) { UKDataContext.setApplicationContext(SpringApplication.run(Application.class, args)); } }
第三步:配置Netty Server相關代碼apache
package com.ukefu.util.server; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import com.corundumstudio.socketio.SocketIOServer; import com.ukefu.core.UKDataContext; import com.ukefu.util.server.handler.AgentEventHandler; import com.ukefu.util.server.handler.IMEventHandler; @Component public class ServerRunner implements CommandLineRunner { private final SocketIOServer server; private IMEventHandler imEventHandler ; private AgentEventHandler agentEventHandler ; @Autowired public ServerRunner(SocketIOServer server , IMEventHandler imEventHandler , AgentEventHandler agentEventHandler) { this.server = server; this.imEventHandler = imEventHandler ; this.agentEventHandler = agentEventHandler ; } public void run(String... args) throws Exception { server.getNamespace(UKDataContext.NameSpaceEnum.IM.toString()).addListeners(imEventHandler); server.getNamespace(UKDataContext.NameSpaceEnum.AGENT.toString()).addListeners(agentEventHandler); server.start(); } }
第四步:配置消息處理的代碼緩存
package com.ukefu.util.server.handler; import java.net.InetSocketAddress; import org.apache.commons.lang.StringUtils; 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.ukefu.util.server.message.AgentStatusMessage; import com.ukefu.util.server.message.ChatMessage; import com.ukefu.util.server.message.NewRequestMessage; @Component public class IMEventHandler extends EventHandler { @Autowired public IMEventHandler(SocketIOServer server) { super(server) ; } @OnConnect public void onConnect(SocketIOClient client) { System.out.println(client.getSessionId()); } //添加@OnDisconnect事件,客戶端斷開鏈接時調用,刷新客戶端信息 @OnDisconnect public void onDisconnect(SocketIOClient client) { System.out.println(client.getSessionId()); } //消息接收入口,網站有新用戶接入對話 @OnEvent(value = "new") public void onEvent(SocketIOClient client, AckRequest request, NewRequestMessage data) { try { String user = client.getHandshakeData().getSingleUrlParam("userid") ; String orgi = client.getHandshakeData().getSingleUrlParam("orgi") ; String session = client.getHandshakeData().getSingleUrlParam("session") ; String appid = client.getHandshakeData().getSingleUrlParam("appid") ; if(!StringUtils.isBlank(session)){ session = session.replaceAll("-", "") ; } if(!StringUtils.isBlank(user)){ /** * 用戶進入到對話鏈接 , 排隊用戶請求 , 若是返回失敗,表示當前坐席全忙,用戶進入排隊狀態,當前提示信息 顯示 當前排隊的隊列位置,不可進行對話,用戶發送的消息做爲留言處理 */ InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress() ; // NewRequestMessage newRequestMessage = OnlineUserUtils.newRequestMessage(user, orgi , session , appid , address.getHostString() , client.getHandshakeData().getSingleUrlParam("osname") , client.getHandshakeData().getSingleUrlParam("browser")) ; // /** // * 加入到 緩存列表 // */ // NettyClients.getInstance().putIMEventClient(user, client); // // if(newRequestMessage!=null && !StringUtils.isBlank(newRequestMessage.getMessage())){ // MessageOutContent outMessage = new MessageOutContent() ; // outMessage.setMessage(newRequestMessage.getMessage()); // outMessage.setMessageType(UKDataContext.MessageTypeEnum.MESSAGE.toString()); // outMessage.setCalltype(UKDataContext.CallTypeEnum.IN.toString()); // // client.sendEvent(UKDataContext.MessageTypeEnum.STATUS.toString(), outMessage); // } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //消息接收入口,坐席狀態更新 @OnEvent(value = "agentstatus") public void onEvent(SocketIOClient client, AckRequest request, AgentStatusMessage data) { System.out.println(data.getMessage()); } //消息接收入口,收發消息,用戶向坐席發送消息和 坐席向用戶發送消息 @OnEvent(value = "message") public void onEvent(SocketIOClient client, AckRequest request, ChatMessage data) { System.out.println(data.getMessage()); } }
第五步:完成配置。服務器
以上全部代碼在優客服中找到。 session