websocket与H5交互程序程序

WebScoketServer


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * WebSocket服务端.
 *
 * @author yuefeng.han
 * @date 2021/1/6
 **/
@ServerEndpoint("/websocket/{sid}")
@Component
@Slf4j
public class WebSocketServer {
  /**
   * 静态变量,用来记录当前在线连接数,把它设计成线程安全的.
   *
   */
  private static AtomicInteger onlineNum = new AtomicInteger();

  /**
   * concurrent 包的线程安全Set, 用来存放每个客户端对应的WebSocketServer对象.
   *
   */
  private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

  /**
   * 建立连接成功调用.
   *
   * @param session session对象
   */
  @OnOpen
  public void onOpen(Session session, @PathParam(value = "sid") String userName) {
    sessionPools.put(userName, session);
    addOnlineCount();
    System.out.println(userName + "加入webSocket" + onlineNum);
    String s = "欢迎" + userName + "加入链接";
    ByteBuffer byteBuffer = ByteBuffer.wrap(s.getBytes(StandardCharsets.UTF_8));
    sendMessage(session, byteBuffer);
  }

  /**
   * 关闭连接时触发.
   *
   * @param userName 用户名
   */
  @OnClose
  public void onClose(@PathParam(value = "sid") String userName) {
    sessionPools.remove(userName);
    subOnlineCount();
    System.out.println(userName + "断开webSocket连接, 当前人数为" + onlineNum);
  }

  /**
   * 收到客户端消息时触发.
   *
   * @param message 消息
   */
  @OnMessage
  public void onMessage(String message, Session session) {
    System.out.println(message);
      //接收来自H5界面的message
//    ObjectMapper om = new ObjectMapper();
//    Map<String, String> map = om.readValue(message, new TypeReference<Map<String, String>>() {});
//    Session session = sessionPools.get(map.get("toUserId"));
//    if (session != null) {
//      try {
//        sendMessage(session, map.get("sendMsg"));
//      } catch (Exception e) {
//        e.printStackTrace();
//      }
//    }
  }

  /**
   * 收到客户端字节数组消息时触发.
   *
   * @param byteBuffer 字节数组消息
   * @param session 当前session
   */
  @OnMessage
  public void onMessage(ByteBuffer byteBuffer, Session session) {
    CharBuffer charBuffer;
    Charset charset = StandardCharsets.UTF_8;
    CharsetDecoder decoder = charset.newDecoder();
      try {
        charBuffer = decoder.decode(byteBuffer);
        System.out.println("收到信息:" + charBuffer.toString());
      } catch (CharacterCodingException e) {
        e.printStackTrace();
      }
    String resultStr = "{message:\" 收到消息 \"}";
    byte[] resultBytes = resultStr.getBytes(StandardCharsets.UTF_8);
    ByteBuffer wrap = ByteBuffer.wrap(resultBytes);
    sendMessage(session, wrap);
  }

  /**
   * 发生连接错误或异常调用.
   *
   * @param throwable 异常信息
   * @param userName 当前服务器连接的session ID
   */
  @OnError
  public void onError(Throwable throwable, @PathParam("sid") String userName) {
    System.out.println("发生错误");
    throwable.printStackTrace();
    try {
      sessionPools.get(userName).close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }


  /**
   * 发送字符串信息.
   *
   * @param session 当前连接的session
   * @param message 消息
   */
  public void sendMessage(Session session, String message) {
    if (session != null) {
      synchronized(session) {
        try {
          session.getBasicRemote().sendText(message);
        } catch (IOException e) {
          String warnMessage = "传送字符串消息错误";
          log.warn("websocketServer: {},{}", warnMessage, e);
        }
      }
    }
  }

  /**
   * 发送字节数组信息.
   *
   * @param session 当前连接的session
   * @param byteBuffer 字节缓冲
   */
  public void sendMessage(Session session, ByteBuffer byteBuffer) {
    if (session != null) {
      synchronized (session) {
        try {
          session.getBasicRemote().sendBinary(byteBuffer);
        } catch (IOException e) {
          String warnMessage = "传送字节数组消息错误";
          log.warn("websocketServer: {},{}", warnMessage, e);
        }
      }
    }
  }

  /**
   * 给指定用户发送字符串信息.
   *
   * @param userName 用户名
   * @param message 消息
   */
  public void sendInfo(String userName, String message) {
    Session session = sessionPools.get(userName);
    sendMessage(session, message);
  }

  /**
   * 给指定用户发送字节数组信息.
   *
   * @param userName 用户名
   * @param byteBuffer 消息
   */
  public void sendInfo(String userName, ByteBuffer byteBuffer) {
    Session session = sessionPools.get(userName);
    sendMessage(session, byteBuffer);
  }

  /**
   * 添加实时在线数.
   */
  public static void addOnlineCount() {
    onlineNum.incrementAndGet();
  }

  /**
   * 减少实时在线数.
   */
  public static void subOnlineCount() {
    onlineNum.decrementAndGet();
  }
}

## H5界面
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"> </script>
</head>
<body>
    <h3>基于web socket 点对点通讯</h3>
    【当前用户ID】:<input id="userId" name="userId" type="text" value="10"><br><br>
    【对方用户ID】:<input id="toUserId" name="toUserId" type="text" value="20"><br> <br>
    【发送信息】:   <input id="sendMsg" name="sendMsg" type="text" value="hello websocket"><br><br>
    【接收信息】:  <span id="receiveMsg" style="color: #800080"></span><br><br>
    <button id="openBtn">开启socket</button><br><br>
    <button id="sendBtn">发送消息</button><br><br>
</body>
<script>
    let socket;
    $("#openBtn").click(function() {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        }else{
            console.log("您的浏览器支持WebSocket");
            //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
            var userId = $('#userId').val();
            var socketUrl="ws://localhost:22598/websocket/10?uniqueId=sip-1-1534847965.97644&enterpriseId=7000101&cno=10001";
            console.log(socketUrl);
            if(socket!=null) {
                socket.close();
                socket=null;
            }
            socket = new WebSocket(socketUrl);
            //打开事件
            socket.onopen = function() {
                console.log("websocket已打开");
            }
            //关闭事件
            socket.onclose = function() {
                console.log("websocket已关闭");
            };
            //发生了错误事件
            socket.onerror = function() {
                console.log("websocket发生了错误");
            };
            //获得消息事件
            socket.onmessage = function(msg) {
                console.log(msg.data);
                $("#receiveMsg").html(msg.data);
            };
        }
    });
    $("#sendBtn").click(function () {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        } else {
            console.log("您的浏览器支持WebSocket");
            var toUserId = $("#toUserId").val();
            var sendMsg = $("#sendMsg").val();
            var o = {};
            o.toUserId = toUserId;
            o.sendMsg = sendMsg;
            var msg = JSON.stringify(o);
            console.log(msg);
            socket.send(msg);
        }
    });
</script>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值