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,欢迎大神指导