WebSocket(java客户端+springboot服务端)
客户端:
package websocketclient; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; import java.net.URI; import java.net.URISyntaxException; import java.nio.ByteBuffer; /** * @Author * @Description * @Date 2018/12/28 0028上午 10:03 **/ public class MyWebSocketClient extends WebSocketClient { public MyWebSocketClient(String url) throws URISyntaxException { super(new URI(url)); // 连接地址 } @Override public void onOpen(ServerHandshake shake) { System.out.println("客户端连接了服务器"); } @Override public void onMessage(String paramString) { System.out.println("接收到消息:"+paramString); } @Override public void onClose(int paramInt, String paramString, boolean paramBoolean) { System.out.println("服务器关闭..."); } @Override public void onError(Exception e) { System.out.println("连接异常"+e); } @Override public void onMessage(ByteBuffer bytes) { super.onMessage(bytes); System.err.println("这里是onmessage:"); } }模拟用户
package websocketclient; import org.java_websocket.WebSocket; import java.net.URISyntaxException; /** * @Author * @Description * @Date 2018/12/28 0028下午 1:30 * 模拟用户操作 **/ public class main { public static void main(String[] args) throws URISyntaxException { MyWebSocketClient client = new MyWebSocketClient("ws://localhost:9090/websocket/2"); client.connect(); while (!client.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {//获取连接状态 System.out.println("还没有打开"); } System.out.println("建立websocket连接"); client.send("asd");//发送消息 } }下面是springboot服务器端:
引入jar包
<!-- java版webSocket服务端 --> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.3.5</version> <scope>test</scope> </dependency> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>RELEASE</version> </dependency>注册服务:
package com.ceshi.sy.WebSocket; import org.apache.catalina.session.StandardSessionFacade; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.socket.server.standard.ServerEndpointExporter; import javax.servlet.http.HttpSession; import javax.websocket.HandshakeResponse; import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpointConfig; import javax.websocket.server.ServerEndpointConfig.Configurator; /** * *开启WebSocket支持 * @Author * @Description * @Date 2018/12/20 0020上午 10:52 **/ @Configuration public class WebSocketConfig extends Configurator { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }注册服务器页面
package com.ceshi.sy.WebSocket; 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.CopyOnWriteArraySet; /** * @Author * @Description * @Date 2018/12/20 0020上午 10:07 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端, * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端 **/ //@ServerEndpoint(value="/websocket",configurator=WebSocketConfig.class) @ServerEndpoint(value="/websocket/{param}") @Component public class WebSocket { //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 private static int onlineCount=0; //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识 private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<WebSocket>(); //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; /** * 连接建立成功调用的方法 * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 */ @OnOpen public void onOpen(Session session,EndpointConfig config){ this.session =session; webSocketSet.add(this); //当前用户加入set中 addOnlineCount(); //在线数加1 System.out.println("有新连接加入!当前在线人数为" + getOnlineCount()); } /** * 连接关闭调用的方法 */ @OnClose public void onClose(){ webSocketSet.remove(this); //从set中删除 subOnlineCount(); //在线数减1 System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 * @param session 可选的参数 */ @OnMessage public void onMessage(@PathParam("param") String name, String message,Session session) { try { if(name!=null) { this.sendInfoByName(name,message); }else {//name为空群发消息 for(WebSocket item: webSocketSet){ item.sendInfo(session.getId(), message += "<br>"); } } } catch (IOException e) { System.err.println("给用户发送消息失败"); } } /** * 发生错误时调用 * @param session * @param error */ @OnError public void onError(Session session, Throwable error){ System.out.println("发生错误"); error.printStackTrace(); } /** * 实现服务器主动群发推送 * @param message * @throws IOException */ //@PathParam("sid") String sid, public void sendMessage(String sid,String message) throws IOException { System.err.println(sid+"给客户端推送消息:"+message); this.session.getBasicRemote().sendText(sid+"说:"); this.session.getBasicRemote().sendText(message); } /** * * * 新用户上线群发状态 * * */ public static void sendInfo(String sid, String message) throws IOException { System.out.println(sid + ":" + message); message+="<br>"; for(WebSocket item : webSocketSet) { try { item.sendMessage(sid, message); }catch(IOException e) { System.err.println("给客户端推送消息失败"); } } } /** * 给某一个用户发消息 * */ //@PathParam("sid") public static void sendInfoByName(@PathParam("sid") String sid,String message) throws IOException { System.out.println("推送消息到窗口"+sid+",推送内容:"+message); for (WebSocket item : webSocketSet) { try { //这里可以设定只推送给这个sid的 item.sendMessage(sid,message); } catch (IOException e) { continue; } } } /** * 统计用户 */ public static synchronized int getOnlineCount() { return onlineCount; } /** * 用户上线加1 */ public static synchronized void addOnlineCount() { WebSocket.onlineCount++; } /** * 用户下线减1 */ public static synchronized void subOnlineCount() { WebSocket.onlineCount--; } }总结:写的匆忙,发消息的逻辑有bug,欢迎大神指导