1

我正在尝试在 javascript 中的客户端应用程序上设置多个 websocket。我的 websockets.js 脚本应该连接到服务器的 websocketserver,然后为事件发射器分配相应的功能。

因为我在同一个网页上有多个连接对象,所以我想我只是制作一个经常使用“this”的函数,这样我就可以写出:

    this.socket.onopen( function(){  
                message('<p class="event">Socket Status: 
                                '+this.socket.readyState+' 
                                (open)',this.chatString);  
                    }   );

问题是当一个事件被触发时,函数已经失去了它的作用域。我在这个 onopen 回调中收到一个错误,提示“无法返回“未定义”的属性 'readyState'。

当我考虑在同一个网页上看到了多少个 websocket 时,我意识到我显然做错了。下面是我的 websockets.js 脚本。请随时指出我完全违反了关于 websockets 的良好编码实践,我一开始只是想测试 websockets,但现在我真的想知道我应该如何在一页上使用多个 websockets。

    // This is the JavaScript file for the basic LabVIEW WebSockets demo.
    // Copyright © 2016 by MediaMongrels Ltd. 

    $(document).ready(function() {  
        connect = function(num,ind){  

            debugger;
            var i = ind.toString();
            this.sendString = '#port'+i+'send';
            this.chatString = '#port'+i+'chat';

            this.host = "ws://localhost:"+num;
            debugger;
            // default uses 80, but this can be changed to any port. Change 'localhost' if connecting to a server running on another IP address.
            try
            {  
                this.socket = new WebSocket(this.host);

                message('<p class="event">Socket Status: '+this.socket.readyState +' (create)',this.chatString);
                // Tell the user the connection has been established
                this.socket.onopen = function(){  
                    message('<p class="event">Socket Status: '+connect.socket.readyState+' (open)',this.chatString);  
                }   
                // Display the received message
                this.socket.onmessage = function(msg){  
                    message('<p class="message">Received: '+msg.data,this.chatString);  
                }  
                // Tell the user the connection has been closed
                this.socket.onclose = function(){  
                    message('<p class="event">Socket Status: '+connect.socket.readyState+' (Closed)',this.chatString);  
                }           
            } 
            catch(exception){  
                message('<p>Error'+exception,this.chatString);  
            }  

            $(this.sendString).keypress(function(event) {  
                if (event.keyCode == '13') {  
                    send(this.sendString);  
                }  
            });     

            // Close the connection from the client side
            $('#port'+num+'disconnect').click(function(){  
                this.socket.close();  
            });

            $('#error').text('port '+i+' processed...');
        }

        function message(msg,ctrl){  
            $(ctrl).append(msg+'</p>');    
        } 

        function send(ctrl){
            var text = $(ctrl).text();  
            $(ctrl).text("");
            if(text==""){  
                message('<p class="warning">Please enter a message');  
                return;  
            } 

            try {  

                connect.socket.send(text);  
                message('<p class="event">Sent: '+text,ctrl.slice(0,6)+'chat')  

            } catch(exception){  
                message('<p class="warning">');  
            } 
        }
        $('#connect').click(function(){var request = new XMLHttpRequest();
            var uri = "socks/"+$('#username').val();
            request.open('GET', uri);
            request.responseType = 'text';
            request.send();
            request.onload = function() {
                if(!("WebSocket" in window))  
                    $('#error').text('Oh no, you need a browser that supports WebSockets.' +
                    'How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>');
                else{
                    s = request.response;
                    if(s!="error!"){
                        var arg = [];
                        for(var i = 0;i<3;i++){
                            if (i==2) 
                                arg[i]=s.slice(0);
                            else{
                                arg[i]=s.slice(0,s.indexOf(","));
                                s = s.slice(s.indexOf(',')+1);
                            }
                        }
                        // new connect(arg[1],2); new connect(arg[2],3); 
                        var connect1 = new connect(arg[0],1);
                        var connect2 = new connect(arg[1],2);
                        var connect3 = new connect(arg[2],3);
                    }
                    else $('#error').val("We couldn't find your username!<p> Please make sure its correct.");
                }
            }; 
        }); 
    });
4

2 回答 2

1

您正在失去上下文,因为您的事件处理程序正在异步工作并且与您的类函数没有连接。您应该将其与this上下文绑定。

this.socket.onopen = function(){
    message('<p class="event">Socket Status:' + connect.socket.readyState + ' (open)' , this.chatString);  
}.bind(this)

也将其应用于其他事件处理程序,例如 onmessage、onclose。所以你不会有任何问题。

于 2019-08-07T17:14:33.793 回答
0

像这样声明一个局部变量: Var that=this; this.socket.onopen(function(){
message('套接字状态:'+that.socket.readyState+'(open)',that.chatString);
} );

于 2019-08-07T17:08:07.013 回答