今天写一个前后端交互的websocket , 本来写着挺顺利的,但测试的时候蒙了,前端websocket发的连接请求竟然连接不上

返回状态Status 报了个404 ,然后看后台onError方法也没触发

只是报了下面几条警告信息

  WARN o.s.web.servlet.PageNotFound | No mapping for GET /websocket/***
  WARN o.s.web.servlet.PageNotFound | No mapping for GET /websocket/***
  WARN o.s.web.servlet.PageNotFound | No mapping for GET /websocket/***

没头绪,就上网找了一下,

  有说 需要配置Websocket 注入ServerEndpointExporter 的 ;

  有说 需要添加websocket jar包的

但看这些操作的缘由,却和我的实际情况不太一样,

不过也照着做试了一下,依然没有变化。。。

不由地怀疑,我是在后端代码那边少写了什么???

于是又仔细看了几遍 几个相关的博客,忽然发现有的加了 @Component 注解,有的没加,有可能问题出现在这里

果然,在加了这个@Component 注解后,网页和后台的websocket 就连接成功了

所以,很怀疑那些博客上没加这个注解的,是不是也能连接成功?觉得还是看官方解释好,坑能少踩点!

后端代码

HtmlSocketServer

package com.cloud.simulator.controller;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint; import org.springframework.stereotype.Component; /**
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
* 即 @ServerEndpoint 可以把当前类变成websocket服务类
*/
//访问服务端的url地址
@ServerEndpoint(value = "/websocket/simulator/{userNo}")
@Component
public class HtmlSocketServer { //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0; //concurrent包的线程安全Map,用来存放每个客户端对应的HtmlSocketServer对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static Map<String, HtmlSocketServer> webSocketMap = new ConcurrentHashMap<String, HtmlSocketServer>() ; //与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//当前发消息的客户端的编号
private String userNo = "" ; public static Map<String, HtmlSocketServer> getWebSocketMap() {
return webSocketMap ;
} /**
* 连接成功后调用的方法
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(@PathParam(value = "userNo") String param, Session session) {
userNo = param ;
this.session = session;
webSocketMap.put(param, this) ;
//在线数加1
addOnlineCount();
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
} /**
* 连接关闭调用方法
*/
@OnClose
public void onClose() {
if ( !userNo.equals("") ) {
webSocketMap.remove(userNo);
//在线数减1
subOnlineCount();
System.out.println("关闭一个连接!当前在线人数为" + getOnlineCount());
}
} /**
* 连接异常
*/
@OnError
public void onError(Throwable error) {
System.out.println("连接异常 ---onError");
error.printStackTrace();
} /**
* 接收到客户短消息
*/
@OnMessage
public void onMessage(String mess) {
System.out.println("接收到客户端消息 --onMessage =" + mess);
} /**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
} /**
* 给指定的人发送消息
* @param message
*/
public void sendToUser(String toUserNo, String message) {
String now = getNowTime();
try {
HtmlSocketServer htmlSocketServer = webSocketMap.get(toUserNo) ;
if ( htmlSocketServer != null ) {
htmlSocketServer.sendMessage(now + "用户" + userNo + "发来消息:" + message);
} else {
System.out.println("当前接收信息的用户不在线");
}
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 给所有人发消息
* @param message
*/
public void sendToAll(String message) {
String now = getNowTime();
//遍历HashMap
for (String key : webSocketMap.keySet()) {
try {
//判断接收用户是否是当前发消息的用户
if ( !userNo.equals(key) ) {
webSocketMap.get(key).sendMessage(now + "用户" + userNo + "发来消息:" + message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 获取当前时间
*
* @return
*/
private String getNowTime() {
Date date = new Date();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = format.format(date);
return time;
} public static synchronized int getOnlineCount() {
return onlineCount;
} public static synchronized void addOnlineCount() {
HtmlSocketServer.onlineCount++;
} public static synchronized void subOnlineCount() {
HtmlSocketServer.onlineCount--;
} }

WebMvcConfig

package com.cloud.simulator.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.server.standard.ServerEndpointExporter; /**
* Spring MVC 配置
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer { private final Logger logger = LoggerFactory.getLogger(WebMvcConfig.class); //服务器支持跨域
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST","OPTIONS")
.allowedHeaders("*")
.exposedHeaders("Access-Control-Allow-Headers",
"Access-Control-Allow-Methods",
"Access-Control-Allow-Origin",
"Access-Control-Max-Age",
"X-Frame-Options")
.allowCredentials(false)
.maxAge(3600);
} /**
* The bean shown in the preceding example registers any @ServerEndpoint
* annotated beans with the underlying WebSocket container. When deployed to a
* standalone servlet container, this role is performed by a servlet container
* initializer, and the ServerEndpointExporter bean is not required.
*
* @return
* 在Spring中可以直接使用Java WebSocket API来提供服务,如果使用内置的web容器,需要做的仅仅是需要在下面添加
*/
/** 注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint 。
* 要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
} }

共同学习,共同进步,若有补充,欢迎指出,谢谢!

Websocket @serverendpoint 404的更多相关文章

  1. java websocket @ServerEndpoint注解说明

    http://www.blogjava.net/qbna350816/archive/2016/07/24/431302.html https://segmentfault.com/q/1010000 ...

  2. WebSocket+Java 私聊、群聊实例

    前言 之前写毕业设计的时候就想加上聊天系统,当时已经用ajax长轮询实现了一个(还不懂什么是轮询机制的,猛戳这里:https://www.cnblogs.com/hoojo/p/longPolling ...

  3. Java使用WebSocket

    网页端的消息推送,一般有以下方式: 轮询方式:客户端定时向服务端发送ajax请求,服务器接收到请求后马上返回消息并关闭连接. 优点:后端程序编写比较容易. 缺点:TCP的建立和关闭操作浪费时间和带宽, ...

  4. WebSocket实现数据库更新前台实时显示

    通过一个小实例来实现数据库更新后,推送消息给前台,让前台进行相应操作. 需求 数据库更新之后服务器推送消息给前台,让前台做操作.(数据库的数据不是由服务器写入的) 实现的话说到底都是用轮询,因为数据库 ...

  5. IDEA Java Web(Spring)项目从创建到打包(war)

    创建Maven管理的Java Web应用 创建新项目,"create new project",左侧类型选择"maven",右侧上方选择自己的SDK,点击&qu ...

  6. 一套简单的web即时通讯——第一版

    前言 我们之前已经实现了 WebSocket+Java 私聊.群聊实例,后面我们模仿layer弹窗,封装了一个自己的web弹窗 自定义web弹窗/层:简易风格的msg与可拖放的dialog,生成博客园 ...

  7. WebSocket handshake: Unexpected response code: 404

    在执行    http://www.cnblogs.com/best/p/5695570.html  提供的 websocket时候, 报错了 “WebSocket handshake: Unexpe ...

  8. WebSocket connection to,Error during WebSocket handshake: Unexpected response code: 404

    使用标准的JSR 356注解时,需要使用tomcat 8.x版本,如果使用tomcat 7.x的版本,则需要继承WebSocketServlet,否则会报WebSocket connection to ...

  9. struts2+websocket报错:failed: Error during WebSocket handshake: Unexpected response code:404

    最近把websocket集成进项目里面来,打开网页总是会遇到这样的错误. 网上说的原因有3种,但是都不适合我,但是也记录下. 1.struts2截拦掉了ws的请求.这种援用可以尝试把web.xml清空 ...

随机推荐

  1. 【VS开发】【Live555-rtsp】在windows 使用vs2008编译live555

    在windows 使用vs2008编译live555 基于 liveMedia的程序,需要通过继承UsageEnvironment抽象类和TaskScheduler抽象类,定义相应的类来处理事件调度, ...

  2. 零零散散的shell笔记

    ls __paddlepalm_* > __palminfo__ 名字以__paddlepalm_开头的文件名打印到后面那个info里面 https://www.runoob.com/linux ...

  3. js-array自增长方式

    function a(){ var colors = ["red","blue","green"]; colors[colors.lengt ...

  4. 自然语言处理工具python调用hanlp的方法步骤

    Python调用hanlp的方法此前有分享过,本篇文章分享自“逍遥自在017”的博客,个别处有修改,阅读时请注意! 1.首先安装jpype 首先各种坑,jdk和python 版本位数必须一致,我用的是 ...

  5. phpstudy 最新版linux 面板 web防火墙后门防护功能教程

    phpstudy linux 面板针对服务器和网站做了全面的安全防护措施,尽可能的防范网站被入侵,留置后门风险,本篇文章着重介绍phpstudy linux 面板其中的一项安全功能 [网站防火墙]之[ ...

  6. flask 接收参数小坑

    前后端分离: 1.get方式: items = dict(request.args.items()) app_name = items["app_name"].strip() 或 ...

  7. Separate String

    Separate String 时间限制: 1 Sec  内存限制: 128 MB提交: 50  解决: 16 题目描述 You are given a string t and a set S of ...

  8. 深入理解计算机系统 第十一章 网络编程 part1 第二遍

    客户端-服务器编程模型 每个网络应用都是基于客户端-服务器模型的.采用这个模型,一个应用是由一个服务器进程和一个或者多个客户端进程组成.服务器管理某种资源,并且通过操作这种资源来为它的客户端提供某种服 ...

  9. c# 后台隐式使用webBrowser

    c#不使用 webBrowser 控件, 在后台加载html流 private void button1_Click(object sender, EventArgs e) { string urlP ...

  10. c# 获取屏幕图片

    Rectangle bounds = Screen.GetBounds(Screen.GetBounds(Point.Empty)); using (Bitmap bitmap = new Bitma ...