后端intellij,前端vscode,部署环境tomcat9
1、在系统主页Main.vue中初始化和关闭websocket,相关的js放在websocket.js文件中
**Main.vue**
import {initWebSocket,closeWebSocket} from '@/commons/websocket.js';
created(){
initWebSocket();
}
destroyed(){
closeWebSocket();
}
websocket.js
内容在网上都可以找到这里只记录一下重点。
1)接收到数据后如何在其他vue里使用,采用记录到store,使用的页面进行监听
**websocket.js**
import store from '@/store';
onmessage=(event)=>{
var message = JSON.parse(event.data);
//publishinfo为store里action里定义的函数
store.dispatch("publishInfo", message);
}
**store的app.js里**
actions: {
publishInfo(store,info){
//在store的state定义好变量message
store.state.message = info;
}
}
**其他需要使用数据的页面**
computed:{
publishInfo(){
return this.$store.state.app.message;
}
},
watch:{
publishInfo(message){
业务代码...
}
}
2)访问后端的websocket的url,在vscode中启动项目的话访问不需要加项目名,在tomcat里启动访问项目的话需要加上项目名,所以在此进行处理,开发环境为空,打包时会加上项目名。
**websocket.js**
const getWsUrl = () => {
var host = serverHost(); //window.location.host
var project = process.env.API_ROOT;
if(process.env.NODE_ENV === "development"){
host = process.env.PROXY_HOST;
project = "";
}
return "ws://" + host + project +"/websocket/" + getContext().user.id;
}
config/dev.env.js
加了PROXY_HOST: ‘“localhost:8888”’
pom.xml加入
<!-- spring boot websocket 依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocketConfig
说明:打包war部署到tomcat时是不需要这个类的,因为tomcat容器已负责管理serverEndPoint,开发环境需要这个类是因为需要让spring来管理serverEndPoint。所以采用@Profile注解,标注开发、测试时加入该类,生产环境就打包该类。然后我在intellij运行/调试配置里程序参数,加入
–spring.profiles.active=dev,用于设置启动时profile参数。这样开发和打包操作就互不影响了。
@Configuration
public class WebSocketConfig extends ServerEndpointConfig.Configurator {
@Bean
@Profile(value = {"dev","test"})
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
WebSocketServer
@Component
@ServerEndpoint(value = "/websocket/{userId}",configurator = WebSocketConfig.class)
public class WebSocketServer {
private String userId;
private Logger log = LoggerFactory.getLogger(WebSocketServer.class);
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId){
this.userId = userId;
WebSocketClient.addSession(userId, session);
log.info("WebSocket连接成功,userId["+this.userId+"]");
}
省略其他方法...
WebSocketClient
public class WebSocketClient {
private static ConcurrentHashMap<String, Session> webSocketSet = new ConcurrentHashMap<>();
public static void addSession(String userId, Session session){
webSocketSet.put(userId, session);
}
public static void removeSession(String userId){
webSocketSet.remove(userId);
}
/**
* 业务调用-发送消息
* @param receiveUserId
* @param message
*/
public static void sendMessage(MessageType type, String receiveUserId, JSONObject message) throws BusinessException {
try{
Session session = webSocketSet.get(receiveUserId);
if(session!=null){
message.put("messageType", type.getName());
session.getBasicRemote().sendText(message.toJSONString());
}
}catch (Exception e){
throw new BusinessException(e.getMessage());
}
}
1、按照网上通常的写法,vscode启动后websocket访问后端404。原因是在vscode里启动前端,websocket的url不需要加入项目名(ws://127.0.0.1:8888/websocket/123)
2、开发环境没问题部署到Tomcat时无法启动,错误:javax.websocket.server.ServerContainer not available,网上多说jar包冲突,最终发现是不需要WebSocketConfig那个类,所以在打包时去掉,我采用的是@Profile(value={“dev”,“test”})注解,因为这个类开发环境还得用。
3、启动tomcat后,前端访问出现错误:Error during WebSocket handshake: Unexpected response code: 404,经过测试发现需要在访问路径上又需要加入项目名(ws://127.0.0.1:8888/project/websocket/123),我的解决办法是在创建wsurl的时候进行判断,开发环境不加项目名,打包时加入项目名。