日常工作中,我们都是使用http请求,来进行前后交互,那么我们也会有使用websocket来进行前后交互的时候,那么它俩有什么区别呢?

http和websocket区别

WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息HTTP是单向的WebSocket是需要浏览器和服务器握手进行建立连接的而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接

根据它的特点就可以知道,如果场景中需要服务端向客户端推送消息,那么使用http就是不行的。所以今天就用spring boot 来接入 WebSocket。

代码实现

1、首先,我们需要在pom文件内引入它的jar包依赖,如下:

org.springframework.boot

spring-boot-starter-websocket

这个时候我们就可以直接利用该第三方的API直接代码实现了。

新增websocket配置类

因为项目中有http请求,也有websocket请求,那么该怎么去区分请求连接的类型呢?这个时候我们需要增加一个websocket的配置类,来进行拦截websocket的请求。

@Configuration

public class WebSocketConfig {

/**

* 注入ServerEndpointExporter,

* 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint

*/

@Bean

public ServerEndpointExporter serverEndpointExporter() {

return new ServerEndpointExporter();

}

}

注意:不要忘记添加 @Configuration 注解,这个类,会自动拦截websocket请求。

完整代码

@Component

@Slf4j

@ServerEndpoint("/websocket/{userId}")

public class WebSocketHandler {

// 接口路径 ws://127.0.0.1:9000/websocket/userId;

private Session session;

//concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。

private static CopyOnWriteArraySet webSocketUtils = new CopyOnWriteArraySet<>();

// 用来存在线连接数

private static Map sessionPool = new HashMap<>();

/**

* 链接成功调用的方法

*/

@OnOpen

public void onOpen(Session session, @PathParam(value = "userId") String userId) {

try {

this.session = session;

webSocketUtils.add(this);

sessionPool.put(userId, session);

sendOneMessage(userId, "连接成功");

//加入队列

QueueUtils.addMap(userId);

log.info("【websocket消息】有新的连接,总数为:" + webSocketUtils.size());

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 链接关闭调用的方法

*/

@OnClose

public void onClose() {

try {

webSocketUtils.remove(this);

log.info("【websocket消息】连接断开,总数为:" + webSocketUtils.size());

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 收到客户端消息后调用的方法

*

* @param message

* @param

*/

@OnMessage

public void onMessage(@PathParam(value = "userId") String userId, String message) {

log.info("【websocket消息】收到客户端消息:" + message);

if (!StringUtils.isEmpty(userId) && !StringUtils.isEmpty(message) && message.equals("ping")) {

sendOneMessage(userId, "pong");

} else {

//1、轮询用户数最少的服务器IP

String serverIP = QueueUtils.getServer();

log.info("serverIP为:" + serverIP);

//2、调用大模型

WebSocketClient client = JavaClient.getClient(userId, serverIP);

if (client != null) {

JSONObject object = new JSONObject();

object.put("", message);

String[][] strings = {{"aaa"}};

object.put("history", strings);

object.put("knowledge_base_id", "/home/nemo/aigc/langchain-ChatGLM/vector_store/knowledge_FAISS_20230516_133609");

//3、发送问题

client.send(object.toString());

}

}

}

/**

* 发送错误时的处理

*

* @param session

* @param error

*/

@OnError

public void onError(Session session, Throwable error) {

log.error("用户错误,原因:" + error.getMessage());

error.printStackTrace();

}

/**

* 推消息给前端

*

* @param userId

* @param message

* @return

*/

public static Runnable sendOneMessage(String userId, String message) {

Session session = sessionPool.get(userId);

if (session != null && session.isOpen()) {

try {

log.info("【推给前端消息】 :" + message);

//高并发下,防止session占用期间,被其他线程调用

synchronized (session) {

session.getBasicRemote().sendText(message);

}

} catch (Exception e) {

e.printStackTrace();

}

}

return null;

}

}

测试

我们可以使用第三方websocket在线测试工具,http://www.jsons.cn/websocket/,连进行测试。

我们可以发送请求连接为:ws://127.0.0.1:9000/websocket/1

然后点击Websocket连接,即客户端可以收到服务端的回应:连接成功。

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: