webSocket--2.打开关闭管道

本文介绍WebSocket的基本交互流程,并通过一个简单的回显实例演示了如何利用WebSocket进行客户端与服务器端的数据交换。涵盖了WebSocket配置、服务端实现及前端JavaScript编程。

1      基本步骤

1.  开启连接

2.  客户端给服务器端发送数据

3.  服务器端接收数据

4.  服务器端给客户端发送数据

5.  客户端接收数据

6.  监听三类基本事件: onopen, onmessage,onclose

提示:   onmessage 是发送数据时的响应事件。

                onopen是打开连接时的响应事件。

                onclose是关闭连接时的响应事件。


 

2      Demo

使用webSocket实现一个单机的 echo练习。

目的是: 熟悉webSocket 客户端和服务器端的API。

 

2.1  WebSocketConfig

2.1.1  参考tomcat

F:\Tomcat\apache-tomcat-7.0.65\webapps\examples\WEB-INF\classes\websocket

 

 

 

2.1.2  demo

package com.bjsxt.config;

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import java.util.Set;

public class WebSocketConfig  implements ServerApplicationConfig {

   /*
    * 上面的两个方法都是用来注册 webSocket的。   只不过注册的方式不同。
    * 1. getAnnotatedEndpointClasses  1方法是注解的方式
    * 2. getEndpointConfigs  2方法是 接口的方式
   * 显然 注解的方式更加的 灵活简单。  接口的方式更加的传统,严谨。
    */

   @Override
   public Set<ServerEndpointConfig>getEndpointConfigs(Set<Class<? extends Endpoint>> set) {
      return null;
   }

   @Override
   public Set<Class<?>>getAnnotatedEndpointClasses(Set<Class<?>> arg0) {
      System.out.println("正在扫描所有的webSocket服务!!!" + arg0.size());
      return arg0;
   }
}

2.1.3  启动tomcat

启动tomcat,输出..,再次验证ServerApplicationConfig启动tomcat之前就开始执行

 

2.2  EchoSocket

2.2.1  参考tomcat

第一步

F:\Tomcat\apache-tomcat-7.0.65\webapps\examples\WEB-INF\classes\websocket\echo

第四步

 

2.2.2  第一步创建一个 socket服务

  

2.2.3  第二步@OnOpen(在index.jsp第二步后)

前端使用发送了服务后,会自动调用此方法

 

启动tomcat点击按钮:

 

2.2.4  第三步@OnClose

关闭连接时,触发

 

2.2.5  第四步@OnMessage(在index.jsp第二步之后)

 

2.2.6  完整Demo

package com.bjsxt.socket;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * Created by lan_jiaxing on 2018/2/1 0001.
 */
@ServerEndpoint("/echo")
public class EchoSocket {

    public EchoSocket() {
        System.out.println("EchoSocket.EchoSocket()");
    }

    @OnOpen
    public void open(Session session){
        //一个session代表一次回话
        System.out.println("sessionId:" + session.getId());
    }

    @OnClose
    public void close(Session session){
        //一个session代表一次回话
        System.out.println("session:" + session.getId() + "通道关闭");
    }

    @OnMessage
    public void message(Session session , String msg){
        System.out.println("客户端:" + msg);
        try {
            session.getBasicRemote().sendText("服务器说:收到了");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


2.3  Index.jsp

2.3.1  参考tomcat

第一步:F:\Tomcat\apache-tomcat-7.0.65\webapps\examples\websocket

 

第二步

  

2.3.2         第一步 前端创建一个WebSocket

此方法会自动调用后台带@OnOpen的方法

 

2.3.3  第二步send()方法(在EchoScoket第三步之后)

 

 

2.3.4  第三步接受服务器端的(在EchoScoket第四步之后)

在subSend方法中添加

 

2.3.5  完整demo

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <button onclick="subOpen()">按钮</button>

  <input id = "msg" /><button onclick="subSend()">send</button>

  <div id="dv"></div>

  <script>
      var ws = null;//一个ws对象就是一个通讯对象
      var target = "ws://localhost:8080/websocket-01/echo"

      function subOpen() {
          if ('WebSocket' in window) {
              ws = new WebSocket(target);
          } else if ('MozWebSocket' in window) {
              ws = new MozWebSocket(target);
          } else {
              alert('WebSocket is not supported by this browser.');
              return;
          }

          ws.onmessage = function (event) {
              var dv = document.getElementById("dv")
              dv.innerHTML += event.data;
          }
      }
      
      function subSend() {
          var msg = document.getElementById("msg").value;
          ws.send(msg);
          document.getElementById("msg").value = '';
      }


  </script>
  </body>
</html>

 

3      前端面向对象改造

3.1  Index.jsp

 

调用构造函数以及初始化函数

<%@page contentType="text/html;charset=UTF-8" language="java" %>
<%
  String contextPath =request.getContextPath();
  String basePath = request.getScheme() +"://" + request.getServerName()+ ":" + request.getServerPort()+ contextPath;
  String webSocketPath = "ws://" + request.getServerName()+ ":" + request.getServerPort()+ contextPath;
%>
<html>
  <head>
    <title>$Title$</title>
    <script>
        var contextPath = '<%=contextPath %>';
        varbashPath = '<%=basePath %>';
        var webSocketPath = '<%=webSocketPath %>';
    </script>
  </head>
  <body>
  <%--<button onclick="subOpen()">连接按钮</button>--%>

  <input id = "msg" /><button id="send">send</button>

  <div id="dv"></div>

  <script type="text/javascript"src= '<%=contextPath %>/js/index.js'></script>
  <script>
    var index = new Index({webSocketPath : webSocketPath}).init();
  </script>
  </body>
</html>
 

1.2  Index.js

构造函数

 

var Index = function(param) {
    this.ws = null;//一个ws对象就是一个通讯对象
    this.target= param.webSocketPath + "/echo";//webSocket的路径,写成target,区分传统http的url
    return this;
}
/**
 * 初始化函数
 * @returns {Index}
 */
Index.prototype.init = function() {
    this.webSocketMsg();
    this.attactEvent();
    return this;
}

/**
 * websocket的一些相关操作:连接,通信,关闭
 * @returns {Index}
 */
Index.prototype.webSocketMsg = function() {
    /* 判断浏览器兼容性,new成功后,1.找到@ServerEndpoint("/echo"),
      2.创立了连接,并执行@OnOpen的方法  */
    if ('WebSocket'in window) {
        this.ws = new WebSocket(this.target);
    } else if ('MozWebSocket' in window) {
        this.ws = new MozWebSocket(this.target);
    } else {
        alert('WebSocket是不被浏览器支持。');
        return;
    }

    //连接成功响应,在后台@OnOpen后执行(了解)
    this.ws.onopen = function () {
       // alert("open........")
    }

    //连接成功响应,在后台@OnClose后执行(了解)
    this.ws.onclose = function () {
        // alert("close........")
    }

    /* event.data就是后台 session.getBasicRemote().sendText("服务器说:收到了")之后响应
       注意:不是针对@OnMessage响应,而是针对 那个方法响应    */
    this.ws.onmessage = function (event) {
        var dv = document.getElementById("dv")
        dv.innerHTML += event.data;
    }
    return this;
}

/**
 * 注册函数相关操作
 * @returns {Index}
 */
Index.prototype.attactEvent = function() {
    var that= this;
    var send= document.getElementById("send");
    send.onclick = function() {
        var msg = document.getElementById("msg").value;
        that.ws.send(msg);
        document.getElementById("msg").value = '';
    }
    return this;
}
 


 

 

 

 

 

 

[root@yfw ~]# cd /opt/openfire [root@yfw openfire]# find /opt/openfire -name "*.log" -type f /opt/openfire/logs/stdoutt.log /opt/openfire/logs/openfire.log /opt/openfire/logs/stderror.log [root@yfw openfire]# # 1. 查看错误日志 [root@yfw openfire]# echo "=== stderror.log ===" === stderror.log === [root@yfw openfire]# cat /opt/openfire/logs/stderror.log 10月 31, 2025 5:50:47 下午 com.sun.jersey.api.core.PackagesResourceConfig init 信息: Scanning for root resource and provider classes in the packages: org.jivesoftware.openfire.plugin [root@yfw openfire]# [root@yfw openfire]# echo "=== openfire.log (last 50 lines) ===" === openfire.log (last 50 lines) === [root@yfw openfire]# tail -n 50 /opt/openfire/logs/openfire.log at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) [netty-common-4.1.108.Final.jar:4.1.108.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.108.Final.jar:4.1.108.Final] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.31 18:07:54.244 ERROR [socket_c2s-thread-4]: org.jivesoftware.openfire.nio.NettyConnection - Problem during connection close or cleanup java.io.IOException: 断开管道 at sun.nio.ch.FileDispatcherImpl.write0(Native Method) ~[?:?] at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) ~[?:?] at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:113) ~[?:?] at sun.nio.ch.IOUtil.write(IOUtil.java:58) ~[?:?] at sun.nio.ch.IOUtil.write(IOUtil.java:50) ~[?:?] at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:462) ~[?:?] at io.netty.channel.socket.nio.NioSocketChannel.doWrite(NioSocketChannel.java:415) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:931) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.flush0(AbstractNioChannel.java:359) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:895) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1372) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:935) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:921) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:907) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:125) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:939) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:957) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:982) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:950) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:1000) ~[netty-transport-4.1.108.Final.jar:4.1.108.Final] at org.jivesoftware.openfire.nio.NettyConnection.close(NettyConnection.java:215) [xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.nio.NettyXMPPDecoder.exceptionCaught(NettyXMPPDecoder.java:71) [xmppserver-4.9.2.jar:4.9.2] at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:317) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.exceptionCaught(DefaultChannelPipeline.java:1377) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.DefaultChannelPipeline.fireExceptionCaught(DefaultChannelPipeline.java:907) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.handleReadException(AbstractNioByteChannel.java:125) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:177) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) [netty-transport-4.1.108.Final.jar:4.1.108.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) [netty-common-4.1.108.Final.jar:4.1.108.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.108.Final.jar:4.1.108.Final] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.31 18:08:34.052 WARN [Jetty-QTP-AdminConsole-33]: org.jivesoftware.admin.LoginLimitManager - Failed admin console login attempt by admin from 61.141.78.188 2025.10.31 18:08:34.054 INFO [Jetty-QTP-AdminConsole-33]: org.jivesoftware.util.cache.CacheFactory - Created cache [org.jivesoftware.util.cache.DefaultLocalCacheStrategy] for Sequences [root@yfw openfire]# [root@yfw openfire]# echo "=== stdoutt.log (last 50 lines) ===" === stdoutt.log (last 50 lines) === [root@yfw openfire]# tail -n 50 /opt/openfire/logs/stdoutt.log Openfire 4.9.2 [2025年10月31日 下午5:50:40] 管理控制台正在侦听: http://0.0.0.0:9090 https://0.0.0.0:9091 Successfully loaded plugin 'admin'. Successfully loaded plugin 'clientcontrol-2.1.10'. Successfully loaded plugin 'jsxc-4.4.0 Release 2'. Successfully loaded plugin 'justmarried-1.3.0'. Successfully loaded plugin 'mucextinfo-1.0.0'. Successfully loaded plugin 'pade-1.9.0'. Successfully loaded plugin 'presence-1.7.4'. Successfully loaded plugin 'pushnotification-1.0.1'. Successfully loaded plugin 'search-1.7.5'. Successfully loaded plugin 'usercreation-1.4.1'. Successfully loaded plugin 'userimportexport-2.8.0'. Successfully loaded plugin 'userservice-2.1.3'. Successfully loaded plugin 'userstatus-1.3.0'. Ignoring plugin 'websocket': compatible with server versions up to but excluding 4.2.0. Current server version is 4.9.2. Successfully loaded plugin 'xmppweb-0.10.3 Release 1'. Successfully loaded plugin 'jabberbrowsing-1.0.1'. Successfully loaded plugin 'fastpath-4.5.1'. Successfully loaded plugin 'contentfilter-1.9.0'. Finished processing all plugins. [root@yfw openfire]#
最新发布
11-01
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值