You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core Razor中WebSocket onopen触发但onmessage在独立JS文件不生效

问题

我尝试通过WebSocket获取消息,代码放在.cshtml文件内时,onopen和onmessage事件均可正常触发;但将相同代码迁移至独立JavaScript文件并在页面中引入后,onopen事件能正常触发,onmessage事件却始终无法触发。

相关代码

.cshtml 文件代码

<script src="https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js"></script>
<script src="~/js/klines-graph.js"></script>
<script>
   var klines = new Klines('@Model.Symbol', '5m');
   klines.createKlines();
</script>

独立JavaScript文件代码

class Klines {
    constructor(symbol, interval) {
        this.symbol = symbol;
        this.interval = interval;
        this.currentPrice = 0;
        this.sum = 0;
        this.onPriceChange = new Event('onPriceChange');
        this.liveKlineSocket = new WebSocket('wss://stream.binance.com:9443/ws/' + symbol + '@@kline_5m');
        const chart = LightweightCharts.createChart(document.getElementById("chart"), {
            width: 800,
            height: 400,
            layout: {
                backgroundColor: '#ffffff',
                textColor: 'rgba(0, 0, 0, 0.9)',
            },
            grid: {
                vertLines: {
                    color: 'rgba(0, 0, 0, 0.9)',
                },
                horzLines: {
                    color: 'rgba(0, 0, 0, 0.9)',
                },
            },
            crosshair: {
                mode: LightweightCharts.CrosshairMode.Normal,
            },
            timeScale: {
                borderColor: 'rgba(0, 0, 0, 0.8)',
                timeVisible: true,
                secondsVisible: false,
            },
        });
        this.candleSeries = chart.addCandlestickSeries();
    }

    createKlines() {
        fetch(`https://api.binance.com/api/v3/klines?symbol=${this.symbol}&interval=${this.interval}`)
            .then(response => response.json())
            .then(klineData => {
                let candleStickList = klineData.map(item => {
                    return {
                        "time": item[0] / 1000,
                        "open": item[1],
                        "high": item[2],
                        "low": item[3],
                        "close": item[4]
                    };
                });
                this.candleSeries.setData(candleStickList);
                this.currentPrice = candleStickList[candleStickList.length - 1].close;

                this.liveKlineSocket.addEventListener('open', function (event) {
                    console.log('Connected to kline websocket');                  
                });
                this.liveKlineSocket.addEventListener('message', function (event) {
                    console.log('message');
                    let candleStick = JSON.parse(event.data);
                    this.candleSeries.update({
                        time: candleStick.openTime / 1000,
                        open: candleStick.open,
                        high: candleStick.high,
                        low: candleStick.low,
                        close: candleStick.close
                    });
                });
            }).catch(er => {
                console.log(er);
            });
    }
}
问题原因
  1. this指向错误:message事件回调使用普通function定义时,回调内部的this指向WebSocket实例而非Klines类实例,导致this.candleSeries为undefined,代码执行到this.candleSeries.update时抛出未捕获错误,后续逻辑(包括console.log('message'))完全无法执行。
  2. Binance数据结构解析错误:Binance返回的WebSocket k线消息嵌套在k字段中,原代码直接访问candleStick.openTime等属性不存在,即使this指向正确也会报错。
  3. WebSocket地址笔误:原代码中WebSocket地址的@@kline_5m应为@kline_5m,多一个@符号可能导致订阅主题异常(虽onopen触发,但可能影响消息接收)。
解决方案

修复this指向

有两种方式修正this指向问题:

方式1:使用箭头函数作为回调

箭头函数继承外层作用域的this(即Klines实例):

this.liveKlineSocket.addEventListener('message', (event) => {
    console.log('message');
    let candleStick = JSON.parse(event.data);
    this.candleSeries.update({
        time: candleStick.k.t / 1000,
        open: candleStick.k.o,
        high: candleStick.k.h,
        low: candleStick.k.l,
        close: candleStick.k.c
    });
});

方式2:提前保存this引用

在回调外部将this赋值给变量,回调内部使用该变量访问Klines实例:

const that = this;
this.liveKlineSocket.addEventListener('message', function(event) {
    console.log('message');
    let candleStick = JSON.parse(event.data);
    that.candleSeries.update({
        time: candleStick.k.t / 1000,
        open: candleStick.k.o,
        high: candleStick.k.h,
        low: candleStick.k.l,
        close: candleStick.k.c
    });
});

修正WebSocket地址

将地址中的@@kline_5m改为@kline_5m:

this.liveKlineSocket = new WebSocket('wss://stream.binance.com:9443/ws/' + symbol + '@kline_5m');

内容的提问来源于stack exchange,提问作者Athanasios Sioppidis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:10:56