springboot+websocket及部署tomcat后404问题的处理

一、开发工具

后端intellij,前端vscode,部署环境tomcat9

二、前端vue+websocket

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”’

二、springboot+websocket

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的时候进行判断,开发环境不加项目名,打包时加入项目名。

你可能感兴趣的:(websocket)