赞
踩
要实现一个简单的聊天机器人,可以使用Spring Boot框架作为后端,使用WebSocket协议实现实时通信,使用VUE作为前端实现聊天界面。
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- junit测试会用到,创建了一个client,连接springboot websocket服务-->
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.1</version>
<scope>test</scope>
</dependency>
这里的WebSocketHandler是自定义的WebSocket处理器,用于处理WebSocket消息。
@Configuration @EnableWebSocket public class WebSocketConfiguration implements WebSocketConfigurer { //拦截器,做了一些权限揽件 @Bean public MyWebSocketInterceptor webSocketInterceptor() { return new MyWebSocketInterceptor(); } @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } @Autowired private MyWebsocketHandler myWebsocketHandler; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) { webSocketHandlerRegistry .addHandler(myWebsocketHandler, "/websocket") .setAllowedOrigins("*") .addInterceptors(webSocketInterceptor()); } }
做了一个简单的拦截器,实现了token校验
public class MyWebSocketInterceptor extends HttpSessionHandshakeInterceptor { private final Logger logger = LoggerFactory.getLogger(getClass()); @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { logger.info("[MyWebSocketInterceptor#BeforeHandshake] Request from " + request.getRemoteAddress().getHostString()); if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request; String token = serverHttpRequest.getServletRequest().getHeader("token"); if (StrUtil.isEmpty(token)) { token = serverHttpRequest.getServletRequest().getParameter("token"); } //这里做一个简单的鉴权,只有符合条件的鉴权才能握手成功 if ("token-123456".equals(token)) { return super.beforeHandshake(request, response, wsHandler, attributes); } else { return false; } } return super.beforeHandshake(request, response, wsHandler, attributes); } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { logger.info("[MyWebSocketInterceptor#afterHandshake] Request from " + request.getRemoteAddress().getHostString()); } }
在项目中创建聊天机器人处理器,用于处理聊天机器人的逻辑。这里可以使用机器人框架,例如ChatterBot,实现聊天机器人的功能。
@Component
public class ChatBotHandler {
private ChatterBot bot;
public ChatBotHandler() throws Exception {
bot = new ChatterBotFactory().create(ChatterBotType.CLEVERBOT).createSession();
}
public String getResponse(String message) throws Exception {
return bot.think(message);
}
}
在构造函数中创建ChatterBot实例,然后实现一个getResponse方法,用于获取聊天机器人的回复。
在项目中创建WebSocket处理器,用于处理WebSocket消息。
@Component
public class WebSocketHandler extends TextWebSocketHandler {
@Autowired
private ChatBotHandler chatBotHandler;
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String response = chatBotHandler.getResponse(message.getPayload());
session.sendMessage(new TextMessage(response));
}
}
这里的WebSocketHandler继承自TextWebSocketHandler,处理文本消息。在handleTextMessage方法中,通过ChatBotHandler获取聊天机器人的回复,然后将回复发送给客户端。
public class WebSocketTest { private static final AtomicInteger count = new AtomicInteger(0); @Test public void test() { URI uri = URI.create("ws://127.0.0.1:8081/websocket"); //注意协议号为ws MyWebSocketClient client = new MyWebSocketClient(uri); client.addHeader("token", "token-123456"); //这里为header添加了token,实现简单的校验 try { client.connectBlocking(); //在连接成功之前会一直阻塞 while (true) { if (client.isOpen()) { client.send("先有鸡还是先有蛋?"); } Thread.sleep(1000000); } } catch (InterruptedException e) { e.printStackTrace(); } } }
服务端收到了消息:
客户端也收到了消息的返回:
<template> <div class="test"> </div> </template> <script> export default { name : 'test', data() { return { websock: null, } }, created() { this.initWebSocket(); }, destroyed() { this.websock.close() //离开路由之后断开websocket连接 }, methods: { initWebSocket() { //初始化weosocket const wsuri = 'ws://127.0.0.1:8081/websocket?token=token-123456'//做了一个简单的授权认证 this.websock = new WebSocket(wsuri) this.websock.onmessage = this.websocketonmessage this.websock.onopen = this.websocketonopen this.websock.onerror = this.websocketonerror this.websock.onclose = this.websocketclose }, websocketonopen() { //此处不做任何处理 }, websocketonerror() { //连接建立失败重连 this.initWebSocket() }, websocketonmessage(e) { const redata = JSON.parse(e.data) //数据接收处理 let chatGPT = { headImg: require('@/assets/img/head_portrait1.png'), name: 'ChatGPT', time: new Date().toLocaleTimeString(), msg: redata[0].text, chatType: 0, //信息类型,0文字,1图片 uid: '1002' //uid } this.sendMsg(chatGPT) this.isSend = false }, websocketsend(Data) { //数据发送 this.websock.send(Data) }, websocketclose(e) { //关闭 console.log('断开连接', e) }, sendText() { if (this.inputMsg) { let chatMsg = { headImg: require('@/assets/img/head_portrait.jpg'), name: '卧龙', time: new Date().toLocaleTimeString(), msg: this.inputMsg, chatType: 0, //信息类型,0文字,1图片 uid: '1001' //uid } this.sendMsg(chatMsg) this.inputMsg = '' this.loading = true this.isSend = true this.websocketsend(chatMsg.msg) } else { this.$message({ message: '消息不能为空哦~', type: 'warning' }) } }, //发送信息 sendMsg(msgList) { this.chatList.push(msgList) this.scrollBottom() }, //获取窗口高度并滚动至最底层 scrollBottom() { this.$nextTick(() => { const scrollDom = this.$refs.chatContent animation(scrollDom, scrollDom.scrollHeight - scrollDom.offsetHeight) }) } }, } </script> <style lang='less'> </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。