Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   websocket на стороне клиента (https://javascript.ru/forum/misc/75257-websocket-na-storone-klienta.html)

Роман Андреевич 17.09.2018 14:25

Еще вопрос, может кто знает, как закрыть соединение????? принудительно.

Вопрос, к тому, что по событию close делаю this.spcket = null, а потом вызываю опять connection то все равно ничего выходит

SuperZen 17.09.2018 16:03

https://developer.mozilla.org/ru/doc...bSocket#close()

Роман Андреевич 18.09.2018 12:20

коллеги, всем спасибо, решил задачу.
Все работает, отлично и быстро

SuperZen 18.09.2018 14:08

что сделал то?)

Роман Андреевич 18.09.2018 14:23

SuperZen, радость была преждевременной)))))))))))))))

Дабы исключить ошибку соединения сокета, я перед созданием экземпляра, пульнул ajax на сервер, и если он мне вернул код 200 то все ок, создаем и вешаем слушатели open и close. по событию close просто снова вызываем connection. Вот код:

'use strict';
window.SocketModule = (function(window) {
        
    class SocketModule {
        
        constructor(options) {
            
            this.socket;
            this.path = options.path;
            this.connection();
            this.reconnectCount = 60;
            
        }
        
        connection() {
            
            const _t = this;
            
            this.checkServer(function(server) {
                
                if (!server) return;
                
                _t.socket = new WebSocket(_t.path);
                
                _t.socket.addEventListener('open', function() {

                    _t.indicatorControl(true);

                });
                
                _t.socket.addEventListener('close', function() {
                    
                    _t.indicatorControl(false);

                    _t.connection();

                });
                
            });
            
            return this;

        }
        
        checkServer(callback) {
            
            let timer;
            const _t = this;
            let count = 0;
            
            timer = setInterval(function() {
                
                const req = new XMLHttpRequest();
            
                req.open('GET', '/api/connect', true);
                req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                
                req.send(null);

                req.addEventListener('load', function() {
                    
                    if (req.status === 200) {
                        
                        clearInterval(timer);
                        
                        callback(true);
                        
                    }

                });
                
                count++;
                
                if (count === _t.reconnectCount) {
                    
                    clearInterval(timer);
                    
                    console.log('Превышен лимит ожидания!');
                    
                }
                
            }, 200);
            
            return this;
                        
        }
        
        sendMessage(event_name, data) {

            if (event_name.constructor.name === 'String') {
                
                const _t = this;
                
//                this.readyStateConnection(function() {
                
                    _t.socket.send(JSON.stringify({event_name, data}));

//                });
                
            } else return;
            
            return this;
            
        }
        
        readyStateConnection(callback) {
            
            let timer;
            clearTimeout(timer);
            
            if (this.socket.readyState === 1) {
                
                callback();
                
            } else {
                
                const _t = this;
                timer = setTimeout(function() {
                    
                    _t.readyStateConnection(callback);
                    
                }, 0);
            }
        }
    
    };
    
    return SocketModule;

})(window);


НО!!!!!!!!!!!!!!!!!!!!!!!!!))))))))))))))))))))) )

Когда я вызываю метод sendMessage в другом классе:

'use strict';
window.Chat = (function(window) {
    
    const options = window.options;
    const socketModule = window.SocketModule;
    const ServiceModule = window.ServiceModule;
    const MessageModule = window.MessageModule;
    
    class Chat {
        
        constructor() {
            
            this.transport = new socketModule({
                
                path: options.socketPath
                
            });
            
        }
        
        init() {
            
            this.transport.sendMessage('chat_message', {
                
                type: 'text',
                text: 'Lorem ipsum dolor sit amet, megatron7000'
            
            });
            
            
            
        }
        
    }
    
    return Chat;
    
})(window);


Эта шайтан машина))) выдает мне - annot read property 'send' of undefined! В методе readyStateConnection this.socket = undefined!!!! если вывести в консоль this, то он есть, а если this.socket его нет.

Роман Андреевич 18.09.2018 14:25

Теперь встал вопрос в том, видимо где я потерял контекст???????!!!!!!!!!! или просто туплю сижу.

SuperZen 19.09.2018 00:37

server.js
var path = require('path')
var http = require('http')
var express = require('express')
var WebSocket = require('ws')

const app = express()
const httpServer = http.createServer(app)
const wss = new WebSocket.Server({ server: httpServer })

app.use(express.static(path.join(__dirname, 'public')))

app.get('/', function (req, res) {
  res.sendfile(path.join(__dirname, 'public', 'index.html'))
})

wss.on('connection', (client) => {
  client.on('message', (message) => {
    console.log('message: ', message)
    client.send('ok')
  })
  client.send('connected')
})

httpServer.listen(2999, () => {
  console.log('started at http://localhost:2999')
})


public/index.html
<html>

<head>

</head>

<body>
  <div id="connection">not connected</div>
  <button id="button">Send</div>
    <script>
      var connection = document.getElementById('connection')
      document.getElementById('button').addEventListener('click', function () {
        ws.send('message')
      })

      var ws

      function connect() {
        console.log('connecting')
        connection.innerHTML = 'connecting...'
        ws = new WebSocket('ws://localhost:2999')
        ws.addEventListener('open', wsOpenEvent)
        ws.addEventListener('close', wsCloseEvent)
        ws.addEventListener('message', wsMessageEvent)
        ws.addEventListener('error', wsErrorEvent)
      }

      function wsOpenEvent(e) {
        console.log('connected')
        connection.innerHTML = 'connected'
      }

      function wsCloseEvent(e) {
        console.log('close')
        connection.innerHTML = 'disconnected'
        setTimeout(() => connect(), 5000)
      }

      function wsMessageEvent(e) {
        console.log('message', e)
      }

      function wsErrorEvent(e) {
        console.log('error', e)
      }

      connect()

    </script>
</body>

</html>


package.json
{
  "name": "web_socket",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "express": "^4.16.3",
    "ws": "^6.0.0"
  },
  "scripts": {
    "start": "node server.js"
  }
}


я так сделал reconnect )
и модули бы делал через webpack или parcel )

Роман Андреевич 19.09.2018 04:32

SuperZen, по сути то же самое, но только Реконнект делает через 5 секунд. Я так тоже сделал сначала)))) но теперь вопрос не в Реконнекте, а в том что контекст потерялся и при вызове из другого места ошибка

Роман Андреевич 19.09.2018 06:46

SuperZen, можно по идее сделать и без проверки доступности сервера, но тогда при создании нового экземпляра будет ошибка в консоли и все. Оборвать попытки, например, через 30 секунд и выдать клиенту сообщение какое нибудь, что серверу кранты. Вот.

У меня задача стоит, сделать коннект по сокет соединению, если обрыв то реконнект. Обязательно что бы модульная система была. Дабы коллеги вникали сразу, что бы использовать можно было в разных модулях.

Роман Андреевич 19.09.2018 06:49

Реконнект сделал, работает отлично. А вызывать не могу в других местах))))))))))))))))))))))


Часовой пояс GMT +3, время: 10:10.