使用websocket open怎么去拿httpsession

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用websocket open怎么去拿httpsession相关的知识,希望对你有一定的参考价值。

参考技术A 首先要继承 ServerEndpointConfig,并实现 modifyHandshake方法,该方法有个
HandshakeRequest参数,代码如下:

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;

public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator

@Override
public void modifyHandshake(ServerEndpointConfig config,
HandshakeRequest request,
HandshakeResponse response)

HttpSession httpSession = (HttpSession)request.getHttpSession();
config.getUserProperties().put(HttpSession.class.getName(),httpSession);



这时可以在实现ServerEndPoint的类中作为configurator参数

package action;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.apache.log4j.Logger;

import common.GetHttpSessionConfigurator;
import common.HTMLFilter;

@ServerEndpoint(value = "/action/websocket/chat",configurator=GetHttpSessionConfigurator.class)
public class ChatAction
private final static Logger log = Logger.getLogger(ChatAction.class);
private static final Set<ChatAction> onlineUsers =
new CopyOnWriteArraySet<ChatAction>();
private String nickname;
private Session session;
private HttpSession httpSession;

@OnOpen
public void start(Session session, EndpointConfig config)
this.session = session;
this.httpSession = (HttpSession) config.getUserProperties()
.get(HttpSession.class.getName());
this.nickname=(String) httpSession.getAttribute("loginOperatorId");
onlineUsers.add(this);
String message = String.format("* %s %s", nickname, " from websocket 上线了...");
broadcast(message);


@OnClose
public void end(Session session)
onlineUsers.remove(this);
String message = String.format("* %s %s",
nickname, " from websocket 已经离开...");
broadcast(message);


@OnMessage
public void incoming(String message, EndpointConfig config)
// Never trust the client
String filteredMessage = String.format("%s: %s",
nickname, HTMLFilter.filter(message.toString()));
broadcast(filteredMessage);


@OnError
public void onError(Throwable t) throws Throwable
log.error("错误: " + t.toString(), t);


private static void broadcast(String msg)
for (ChatAction client : onlineUsers)
try
synchronized (client)
client.session.getBasicRemote().sendText(msg);

catch (IOException e)
log.debug("错误: 消息发送失败!", e);
onlineUsers.remove(client);
try
client.session.close();
catch (IOException e1)
// Ignore

String message = String.format("* %s %s",
client.nickname, " from websocket 已经离开...");
broadcast(message);



本回答被提问者和网友采纳

uniapp连接websocket报错?

论坛问题: https://ask.dcloud.net.cn/question/74505

使用: uni.connectSocket(OBJECT) 和  SocketTask.onOpen(CALLBACK) 在安卓手机无法触发websocket的open方法

解决办法使用plus-websocket插件

https://ext.dcloud.net.cn/plugin?id=647

注意方法使用:

socket.connectSocket(OBJECT)

  • socket.onSocketOpen(CALLBACK)
  • socket.onSocketError(CALLBACK)
  • socket.sendSocketMessage(OBJECT)
  • socket.onSocketMessage(CALLBACK)
  • socket.closeSocket(OBJECT)
  • socket.onSocketClose(CALLBACK)

转载大佬的插件案例: https://www.jianshu.com/p/241fd3a81c3f

技术图片
/**uni websocket工具类*/
//npm i plus-websocket --save
import socket from ‘plus-websocket‘
export default class websocket {
    constructor({
        heartCheck,
        isReconnection
    }) {
        // 是否连接
        this._isLogin = false;
        // 当前网络状态
        this._netWork = true;
        // 是否人为退出
        this._isClosed = false;
        // 心跳检测频率
        this._timeout = 3000;
        this._timeoutObj = null;
        // 当前重连次数
        this._connectNum = 0;
        // 心跳检测和断线重连开关,true为启用,false为关闭
        this._heartCheck = heartCheck;
        this._isReconnection = isReconnection;
        // this._onSocketOpened();
    }
    // 心跳重置
    _reset() {
        clearTimeout(this._timeoutObj);
        return this;
    }
    // 心跳开始
    _start() {
        let _this = this;
        this._timeoutObj = setInterval(() => {
            //发送心跳
            _this.sendHeartbeatData();
        }, this._timeout);
    }
    // 监听websocket连接关闭
    onSocketClosed(options) {
        socket.onSocketClose(err => {
            console.log(‘当前websocket连接已关闭,错误信息为:‘ + JSON.stringify(err));
            // 停止心跳连接
            if (this._heartCheck) {
                this._reset();
            }
            // 关闭已登录开关
            this._isLogin = false;
            // 检测是否是用户自己退出小程序
            if (!this._isClosed) {
                // 进行重连
                if (this._isReconnection) {
                    this._reConnect(options)
                }
            }

        })
    }
    // 检测网络变化
    onNetworkChange(options) {

        uni.onNetworkStatusChange(res => {
            console.log(‘当前网络状态:‘ + res.isConnected);
            if (!this._netWork) {
                this._isLogin = false;
                // 进行重连
                if (this._isReconnection) {
                    this._reConnect(options)
                }
            }
        })
    }
    _onSocketOpened() {
        socket.onSocketOpen(res => {
            console.log(‘【websocket】已打开‘);
            // 打开已登录开关
            this._isLogin = true;
            // 发送心跳
            if (this._heartCheck) {
                this._reset()._start();
            }
            // 发送登录信息
            this.sendLoginData();
            // 打开网络开关
            this._netWork = true;
        })
    }
    // 接收服务器返回的消息
    onReceivedMsg(callBack) {
        socket.onSocketMessage(event => {
            let msg = this.socketEventDataToStr(event)
            // console.log(msg);
            if (typeof callBack == "function") {
                callBack(msg)
            } else {
                console.log(‘参数的类型必须为函数‘)
            }
        })
    }

    // 建立websocket连接
    initWebSocket(options) {

        let _this = this;
        if (this._isLogin) {
            console.log("您已经登录了");
        } else {
            // 检查网络
            uni.getNetworkType({
                success(result) {
                    if (result.networkType != ‘none‘) {
                        // 开始建立连接
                        console.log(‘建立websocket连接‘ + options.url);
                        socket.connectSocket({
                            url: options.url,
                            success(res) {
                                if (typeof options.success == "function") {
                                    options.success(res)
                                    _this._onSocketOpened();
                                } else {
                                    console.log(‘参数的类型必须为函数‘)
                                }
                            },
                            fail(err) {
                                if (typeof options.fail == "function") {
                                    options.fail(err)
                                } else {
                                    console.log(‘参数的类型必须为函数‘)
                                }
                            }
                        })
                    } else {
                        console.log(‘网络已断开‘);
                        _this._netWork = false;
                        // 网络断开后显示model
                        uni.showModal({
                            title: ‘网络错误‘,
                            content: ‘请重新打开网络‘,
                            showCancel: false,
                            success: function(res) {
                                if (res.confirm) {
                                    console.log(‘用户点击确定‘)
                                }
                            }
                        })
                    }
                }
            })
        }
    }
    // 发送websocket消息
    sendWebSocketMsg(options) {
        this.sendBinary(1,options);
    }

    //发送心跳连接
    sendHeartbeatData() {
        this.sendBinary(99, {
            data: {},
            success(res) {
                console.log(‘【websocket】心跳连接成功‘)
            },
            fail(err) {
                console.log(‘【websocket】心跳连接失败‘)
                console.log(err)
            }
        });
    }

    //发送第一次连接数据
    sendLoginData() {
        this.sendBinary(99, {
            data: {},
            success(res) {
                console.log(‘【websocket】第一次连接成功‘)
            },
            fail(err) {
                console.log(‘【websocket】第一次连接失败‘)
                console.log(err)
            }
        });
        // this.sendBinary(99, {});
        // socket.sendSocketMessage({
        //  // 这里是第一次建立连接所发送的信息,应由前后端商量后决定
        //  data: JSON.stringify({
        //      "key": ‘value‘
        //  })
        // })
    }

    // 重连方法,会根据时间频率越来越慢
    _reConnect(options) {
        let timer, _this = this;
        if (this._connectNum < 20) {
            timer = setTimeout(() => {
                this.initWebSocket(options)
            }, 3000)
            this._connectNum += 1;
        } else if (this._connectNum < 50) {
            timer = setTimeout(() => {
                this.initWebSocket(options)
            }, 10000)
            this._connectNum += 1;
        } else {
            timer = setTimeout(() => {
                this.initWebSocket(options)
            }, 450000)
            this._connectNum += 1;
        }
    }
    // 关闭websocket连接
    closeWebSocket() {
        socket.closeSocket();
        this._isClosed = true;
    }

    //发送二进制
    sendBinary(commendType, options) {
        let sendMsg = options.data
        let uint8Array = new TextEncoder().encode(JSON.stringify(sendMsg));
        let byteArr = new ArrayBuffer(4 + uint8Array.length);
        //DataView有三个参数,后两个可以缺省;每一个要是ArrayBuffer对象或SharedArrayBuffer对象
        let dv = new DataView(byteArr);
        dv.setUint32(0, commendType, false);
        for (let i = 0; i < uint8Array.length; i++) {
            dv.setUint8(4 + i, uint8Array[i]);
        }
        // console.log(dv);
        socket.sendSocketMessage({
            data: dv.buffer,
            success(res) {

                if (typeof options.success == "function") {
                    options.success(res)
                } else {
                    console.log(‘参数的类型必须为函数‘)
                }
            },
            fail(err) {
                if (typeof options.fail == "function") {
                    options.fail(err)
                } else {
                    console.log(‘参数的类型必须为函数‘)
                }
            }
        });
    }

    //转化方法
    socketEventDataToStr(event) {
        let dv = new DataView(event.data);
        let commendType = dv.getUint32(0, true);
        let slice = event.data.slice(4, event.data.length);
        let unit8Arr = new Uint8Array(slice);
        let s = new TextDecoder("utf-8").decode(unit8Arr);
        console.log("【websocket】标志位:" + commendType);
        console.log("【websocket】返回信息:" + s);
        return s;
    }

}
转载简书大佬的案例

 

以上是关于使用websocket open怎么去拿httpsession的主要内容,如果未能解决你的问题,请参考以下文章

打开 websocket 连接时 on_open 函数无法运行?

使用WebSocket实现聊天室

使用WebSocket实现聊天室

SignalR Asp.netcore 和 angular(WebSocket 未处于 OPEN 状态)断开信号R.HttpTransportType.WebSockets

当我在 Open*** 后面时,浏览器在建立 WebSocket 连接一秒后关闭并显示错误 1006

C# 我获得二进制文件流怎么转化为EXCEL对象?之前是通过路径去拿一个EXCEL文件现在只有一个文件流