java tomcat的websocket

普通servlet方式和spring方式实现websocket

  1. 普通servlet,依赖如下
    1.  <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.1</version>
            <scope>provided</scope>
          </dependency>
         
      <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
          </dependency>
      
          <!--jsp -->
          <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
          <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
          </dependency>

服务器端创建:

@ServerEndpoint("/chat")
public class EchoEndpoint {
    private static int onlineCount = 0;
    private static CopyOnWriteArraySet<EchoEndpoint> webSocketSet = new CopyOnWriteArraySet<EchoEndpoint>();
    private Session session;

    synchronized void  addOnlineCount(){
        onlineCount++;
    }
    int getOnlineCount(){
         return onlineCount;
    }
   synchronized void subOnlineCount(){
       onlineCount--;
    }

    @OnOpen
    public void onOpen(Session session){
        this.session = session;
        webSocketSet.add(this);     //加入set中
        addOnlineCount();           //在线数加1
        System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
    }

    @OnClose
    public void onClose(){
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
        System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端的消息:" + message);
        //群发消息
        for(EchoEndpoint item: webSocketSet){
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    @OnError
    public void onError(Session session, Throwable error){
        System.out.println("发生错误");
        error.printStackTrace();
    }

    public void sendMessage(String message) throws IOException{
        this.session.getBasicRemote().sendText(message);
    }

}

注意注解也是不能少的。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML>
<html>
<head>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

    <base href="<%=basePath%>">
    <title>My WebSocket</title>
</head>

<body>
Welcome<br/>
<input id="text" type="text" />
<button id="login" >登录</button>
<button id="send" onclick="send()">发送</button>
<button id="close" onclick="closeWebSocket()">关闭</button>
<div id="message">
</div>
</body>

<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        $("#login").click(function(){
            websocket = new WebSocket("ws://localhost:80/chat");

            //连接发生错误的回调方法
            websocket.onerror = function(){
                setMessageInnerHTML("error");
            };

            //连接成功建立的回调方法
            websocket.onopen = function(event){
                setMessageInnerHTML("open");
                $("#login").hide(); //隐藏登录按钮
            };

            //接收到消息的回调方法
            websocket.onmessage = function(){
                setMessageInnerHTML(event.data);
            };

            //连接关闭的回调方法
            websocket.onclose = function(){
                setMessageInnerHTML("close");
                $("#login").show(); //显示登录按钮
                $("#send").hide(); //显示登录按钮
                $("#close").hide(); //显示登录按钮

            };

        });
    }
    else{
        alert('Not support websocket');
    }



    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    };

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

页面如上。不需要配置web.xml也没有其他配置,启动服务器就可以了。

 

2.springWebsocket

<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <!--jsp -->
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
      <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api -->
    <dependency>
      <groupId>javax.websocket</groupId>
      <artifactId>javax.websocket-api</artifactId>
      <version>1.1</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>

 

配置文件:

   <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
         <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <mvc:annotation-driven></mvc:annotation-driven>
    <context:component-scan base-package="Springsocket"></context:component-scan>
    <context:annotation-config />

     <bean
      class="org.springframework.web.servlet.view.InternalResourceViewResolver"
     id="internalResourceViewResolver">
        <!-- 前缀 -->
       <property name="prefix" value="/WEB-INF/jsp/" />
       <!-- 后缀 -->
       <property name="suffix" value=".jsp" />
   </bean>

</beans>

写一个类集成此类,方法名字写的很形象:

public class WebSocketHandler extends TextWebSocketHandler {

    //用于保存连接的用户
    private List<WebSocketSession>list =new ArrayList<WebSocketSession>();


    @Override //连接创建完成的意思吗
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("一位客户连接上来");
        list.add(session);
    }

    @Override //处理text消息
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("收到消息:"+message);
        for (WebSocketSession webSocketSession : list) {
            webSocketSession.sendMessage(message);
        }

    }

    @Override //发生错误的意思吗
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        list.remove(session);
        System.out.println("出错");
        exception.printStackTrace();
    }

    @Override  //连接关闭
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        list.remove(session);
        System.out.println("连接关闭");
    }


}

 

写一个配置类,将上面的handler类注册进去,注意注解:

@Configuration
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        String url ="/socket";
        registry.addHandler(webSocketHandler(),url);

    }

    @Bean
public TextWebSocketHandler webSocketHandler(){
        return new WebSocketHandler();
}

}

index.jsp上面修改这个地址:

 

启动服务器即可。

其他,websocket连接还可以添加拦截器,方法是:

写一个类实现此接口:

public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {


    @Override //之前
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        return false;
    }

    @Override //之后
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

    }
}

 

在上面配置handler时顺便配置拦截器即可:

@Configuration
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        String url ="/socket";
        registry.addHandler(webSocketHandler(),url).addInterceptors(handshakeInterceptor());

    }

    @Bean
public TextWebSocketHandler webSocketHandler(){
        return new WebSocketHandler();
}
    @Bean
public HandshakeInterceptor handshakeInterceptor(){
        return new WebSocketHandshakeInterceptor();
}

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Tomcat中配置WebSocket,需要进行以下步骤: 1. 确认Tomcat的版本是否支持WebSocketTomcat 7及以上版本支持WebSocket,如果你使用的是更早版本的Tomcat,则需要升级版本。 2. 在Tomcat的配置文件server.xml中,找到Connector元素。Connector元素通常在文件末尾,类似如下所示: ```xml <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ``` 3. 在Connector元素中添加WebSocket支持。添加如下属性: ```xml <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" maxHttpHeaderSize="8192" protocolHandlerClassName="org.apache.coyote.http11.Http11NioProtocol" upgradeProtocol="org.apache.coyote.http2.Http2Protocol" /> ``` 其中,upgradeProtocol指定了升级的协议类型。如果需要支持WebSocket,则需要设置为"org.apache.coyote.http11.upgrade.UpgradeProtocol"。 4. 在web.xml文件中添加WebSocket的Servlet。在web.xml中添加如下代码: ```xml <servlet> <servlet-name>myWebSocketServlet</servlet-name> <servlet-class>com.example.MyWebSocketServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>myWebSocketServlet</servlet-name> <url-pattern>/myWebSocket</url-pattern> </servlet-mapping> ``` 其中,servlet-class指定了WebSocket的Servlet类,url-pattern指定了WebSocket的URL路径。 5. 编写WebSocket的Servlet类。编写一个类,继承自javax.websocket.Endpoint类,实现WebSocket的相关方法。例如: ```java import javax.websocket.*; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/myWebSocket") public class MyWebSocketServlet { @OnOpen public void onOpen(Session session) { // WebSocket连接建立时调用的方法 System.out.println("WebSocket opened: " + session.getId()); } @OnMessage public void onMessage(String message, Session session) { // 接收到WebSocket消息时调用的方法 System.out.println("Received message: " + message); } @OnClose public void onClose(Session session) { // WebSocket连接关闭时调用的方法 System.out.println("WebSocket closed: " + session.getId()); } @OnError public void onError(Throwable throwable) { // WebSocket出现错误时调用的方法 System.out.println("WebSocket error: " + throwable.getMessage()); } } ``` 6. 部署应用程序并启动Tomcat。将编写好的应用程序部署到Tomcat的webapps目录下,并启动Tomcat服务器。 现在,你已经成功地在Tomcat中配置了WebSocket,并编写了WebSocket的Servlet类。你可以使用WebSocket客户端连接到你的WebSocket服务器并发送消息,测试WebSocket是否正常工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值