Простой безопасный веб-сокет (wss) чат с использованием сервера Node.js и клиента Jquery - PullRequest
0 голосов
/ 06 января 2019

Я добавил голос в этот чат, так что теперь это комбинированный голосовой / текстовый чат. Вы можете найти мой вклад на github по следующему адресу:

https://github.com/HowardRichman/simple-text-voice-chat-in-node-and-javascript

Вот рабочий пример безопасного чата websocket с использованием сервера Node.js и javascript-клиента jquery в Centos 6.9. Здесь задействованы только два файла: (1) server.js и (2) client.htm.

Вот код для server.js, который я запускаю с помощью следующей командной строки linux: node server.js

const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');

const server = new https.createServer({
  cert: fs.readFileSync('/var/cpanel/ssl/apache_tls/example.com/combined'),
  key: fs.readFileSync('/var/cpanel/ssl/apache_tls/example.com/combined')
});
const wss = new WebSocket.Server({ server });
var msg;

wss.on('connection', function connection(ws) 
{
  ws.on('message', function incoming(message) 
  {
    msg = message;
    console.log('received: %s', msg);
    wss.clients.forEach(function (client) 
    {
       if (client.readyState == WebSocket.OPEN) 
       {
          client.send( msg );
       }
    });
  });

  ws.send('Chat room is working!');
});

server.listen(8089);

Примечания:

  1. Вы должны изменить пути, указанные выше, на пути к вашему защищенному сертификату и ключу. Я нашел эти пути в файле httpd.conf моего сервера.

  2. При желании вы можете изменить порт с 8089 в этом и клиентского файла на другой доступный порт. (Порты от 8081 до 8099 обычно доступны.)

Вот код файла client.htm, доступ к которому осуществляется по URL-адресу https (например, https://example.com/client.htm):

<!DOCTYPE html>
<html>
<head>
<TITLE>Chat Client</TITLE>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var webSocket;
var firstTime = true;

function connectWsChat()
{
  try 
  {
    window.WebSocket = window.WebSocket || window.MozWebSocket;
    var host = 'wss://example.com:8089/';
    webSocket = new WebSocket( host );
     webSocket.onopen = function() 
     {
      var chatUser = $( '#chatUser' ).val();
      webSocket.send( '<p>' + chatUser + ' has entered the chat room' );
       $( '#chatButton' ).text( 'Disconnect' );
     }
     webSocket.onmessage = function( msg ) 
     {
        logWsChatMessage( '<p class="message">' + msg.data + '</p>' );
     }
     webSocket.onclose = function() 
     {
      var chatUser = $( '#chatUser' ).val();
       logWsChatMessage( '<p>' + chatUser + ' has left the chat room</p>' );
       // $( '#chatButton' ).text( 'Connect' );
     }
   } 
   catch( exception ) 
   {
      logWsChatMessage( '<p>Error ' + exception + '.</p>' );
   }
}

function isConnectedWsChat() {
  if( webSocket && webSocket.readyState==1 ) {
    $( '#chatButton' ).text( 'Disconnect' );
    return 1;
  }
}

function playSound(){
    var audio = new Audio('notify.mp3');
    audio.play();   
}


function sendWsChat() {
  var chatLog = $( '#chatLog' );
  if( isConnectedWsChat() ) {
    var chatUser = $( '#chatUser' ).val();
    var chatText = $( '#chatText' ).val();
    if( chatUser=='' || chatText=='' ){
      return;
    }
    try{
      chatLog.scrollTop( chatLog.prop( 'scrollHeight' ) );
      webSocket.send( chatUser + ': ' + chatText );
      //logWsChatMessage( '<p class="event">Sent: ' + chatText + '</p>' )
    } catch( exception ){
      logWsChatMessage( '<p class="warning"> Error: ' + exception + '</p>' );
    }
    $( '#chatText' ).val( '' );
  }
}

function logWsChatMessage(msg) {
  var chatLog = $( '#chatLog' );
  var sTop = Math.round( chatLog.prop( 'scrollTop') );
  var sHeight = chatLog.prop( 'scrollHeight' );
  var cHeight = chatLog.prop( 'clientHeight' );

  chatLog.append( '<p>' + msg + '</p>' );

  if (firstTime) 
  {
    chatLog.scrollTop( chatLog.prop( 'scrollHeight' ) );
    firstTime = false;
  } 
  else if (sTop + cHeight == sHeight ) 
  {
    chatLog.scrollTop( chatLog.prop( 'scrollHeight' ) );
  }
  playSound();
}

$(document).ready( function() {

  if( !( 'WebSocket' in window ) ) {
    $( '#chatInput').fadeOut( 'fast' );
    $( '<p>Oh no, you need a browser that supports WebSockets.</p>' )
        .appendTo( '#chatContainer' );
  } else {
    connectWsChat();
  }

  $( '#chatText' ).keypress( function( event ) {
    if( event.keyCode == '13' ) {
      sendWsChat();
    }
  });

  $( '#startButton' ).click( function() {
     window.open('chat.pl','_self');
  });

  $( '#saveButton' ).click( function() {
     window.open('chat1.pl','_self');
  });


  $( '#chatButton' ).click( function() {
    if( webSocket && webSocket.readyState==1 ) {
      var chatUser = $( '#chatUser' ).val();
      webSocket.send( '<p>' + chatUser + ' has left the chat room.</p>' );
      webSocket.close();
      $( this ).text( 'Connect' );
    } else {
      //webSocket.open();
      connectWsChat();
      $( this ).text( 'Disconnect' );
    }
  });

  $( window ).on ("unload", function(e) {
    if( webSocket && webSocket.readyState==1 ) {
      var chatUser = $( '#chatUser' ).val();
      webSocket.send( '<p>' + chatUser + ' has left the chat room.</p>' );
      webSocket.close();
    }
  });

});
</script>
<div id="chatContainer">
<div id="chatLog">
</div>
<div id="chatInput">
<p>Name: <input id='chatUser' type="text" size=40 />
<br>Text: <input id="chatText" type="text" size=40 />
<br><button id="chatButton">Chat not yet set up</button>
</p>
</div>
</div>
</body>
</html>

Примечания:

  1. Измените example.com на имя вашего сайта.

  2. Я тестировал этот код только в Chrome и Firefox. В Firefox имя пользователя автоматически появляется в поле имени, когда пользователь входит в чат, если он или она были в комнате чата ранее. Этого не происходит в Chrome, но вы, вероятно, могли бы использовать cookie, чтобы убедиться, что имя появляется в Chrome.

  3. Пользователь публикует сообщения, нажав «Ввод».

  4. Звуковой файл notify.mp3 - это звуковой сигнал, который воспроизводится при получении нового сообщения с сервера. Я не включил этот файл здесь.

  5. Команды, касающиеся прокрутки и высоты клиента, позволяют пользователю прокручивать вверх, чтобы прочитать более ранние сообщения в быстро меняющемся чате, без необходимости опускаться вниз при появлении новых сообщений. Мой файл CSS (не включен) включает в себя Команда max-height для раздела chatLog, которая может понадобиться, чтобы заставить это работать. Вот часть моего кода CSS: #chatLog {max-height: 430px; переполнение-у: авто; ширина: 100%} * +1049 *

Мой вопрос:

Незадолго до того, как этот чат заработал, я работал над другим решением и загрузил mod_proxy_wstunnel.so в свой конфигурационный файл Apache. Я не знаю, было ли это необходимо.

У меня такой вопрос: можете ли вы запустить безопасный чат через веб-сокет, если у вас не загружен файл mod_proxy_wstunnel.so?

...