implementation group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.0.1.RELEASE'
服务器端:
@Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
package cn.socket; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @Component @ServerEndpoint("/pull/test/{id}") public class WebSocketServer { public WebSocketServer() { System.out.println("---------创建socket---------"); } private static int onlineCount = 0; private static ConcurrentHashMap<String, WebSocketServer> webSocketSet = new ConcurrentHashMap<>(); private static CopyOnWriteArraySet<WebSocketServer> webSockets =new CopyOnWriteArraySet<>(); //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; private static Logger log = LogManager.getLogger(WebSocketServer.class); private String id = ""; /** * 连接建立成功调用的方法*/ @OnOpen public void onOpen(@PathParam(value = "id") String id, Session session) { this.session = session; this.id = id;//接收到发送消息的人员编号 webSocketSet.put(id, this); //加入set中 webSockets.add(this); addOnlineCount(); //在线数加1 log.info("用户"+id+"加入!当前在线人数为" + getOnlineCount()); try { sendMessage("连接成功"); } catch (IOException e) { log.error("websocket IO异常"); } } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { webSocketSet.remove(this); //从set中删除 subOnlineCount(); //在线数减1 log.info("有一连接关闭!当前在线人数为" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息*/ @OnMessage public void onMessage(String message, Session session) { log.info("来自客户端的消息:" + message); //可以自己约定字符串内容,比如 内容|0 表示信息群发,内容|X 表示信息发给id为X的用户 String sendMessage = message.split("[|]")[0]; String sendUserId = message.split("[|]")[1]; try { if(sendUserId.equals("0")) sendtoAll(sendMessage); else sendtoUser(sendMessage,sendUserId); } catch (IOException e) { e.printStackTrace(); } } /** * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("发生错误"); error.printStackTrace(); } public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } /** * 发送信息给指定ID用户,如果用户不在线则返回不在线信息给自己 * @param message * @param sendUserId * @throws IOException */ public void sendtoUser(String message,String sendUserId) throws IOException { if (webSocketSet.get(sendUserId) != null) { if(!id.equals(sendUserId)) webSocketSet.get(sendUserId).sendMessage( "用户" + id + "发来消息:" + " <br/> " + message); else webSocketSet.get(sendUserId).sendMessage(message); } else { //如果用户不在线则返回不在线信息给自己 sendtoUser("当前用户不在线",id); } } /** * 发送信息给所有人 * @param message * @throws IOException */ public void sendtoAll(String message) throws IOException { for (String key : webSocketSet.keySet()) { try { webSocketSet.get(key).sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } public void sendtoAll2(String message) throws IOException { for (WebSocketServer webSocket : webSockets) { try { webSocket.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; } public static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; } }
@RestController("outController") @Api(tags = "外部接口管理") @CrossOrigin //跨域访问 swagger 要使用到 public class OutController extends BaseController { @Autowired private WebSocketServer webSocketServer; @ApiOperation("推送数据") @GetMapping("/toHome") public void toHome() throws Exception { webSocketServer.sendtoAll2("1"); } }
前端代码:
<!DOCTYPE html> <html style="height: 100%;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <title>创建缓冲区</title> </head> <body style="height: 100%;"> <script type="text/javascript"> const ws=new WebSocket('ws://localhost:33002/tianjin-cim/tuchu/apis/pull/test/1'); ws.onmessage =function(e){ console.log(e) }; </script> </body> </html>
websocket通过外网走域名访问
nginx的配置
server {
listen 80;监听端口
server_name roger.com;//域名
add_header Access-Control-Allow-Origin *;
#charset koi8-r;
#access_log logs/host.access.log main;
include D:/nginx-1.8.1/conf/conf.d/*.conf;
server_tokens off;
}
location /a/b {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_pass http://localhost:20069/a/b;//后台服务地址
}
前端websocket地址: <script type="text/javascript"> const ws=new WebSocket('ws://www.roger.com/a/b/socket/register'); ws.onmessage =function(e){ console.log(e) };