thoov / mock-socket

Javascript mocking library for WebSockets and Socket.IO
MIT License
800 stars 119 forks source link

Multiple sockets share connection #18

Open Ghirigoro opened 9 years ago

Ghirigoro commented 9 years ago

If you create multiple sockets pointing to the same server they will all share a single connection (i.e. when one is connected they all are, when a message is sent to one they all receive it, etc.)

NOTE: I ran into this running mocha tests in Node.

thoov commented 9 years ago

@Ghirigoro thanks for finding this. let me look into it and send an update.

nicholasjstock commented 9 years ago
window.WebSocket = MockSocket;

var wss = new MockServer('ws://localhost:8281');

wss.on('connection', function(ws) {
  ws.send("msgSSS"); //This seems to broadcast to all clients, when I would assume it would only send to the current client.
});

var sock1 = new WebSocket('ws://localhost:8281');

var sock1MessageCount = 0;

sock1.onmessage = function(e) {
    sock1MessageCount ++;
    console.log("sock1 onmessageCount:" + sock1MessageCount)
};

var sock2 = new WebSocket('ws://localhost:8281');

var sock2MessageCount = 0;

sock2.onmessage = function(e) {
  sock2MessageCount ++;
  console.log("sock2 onmessageCount:" + sock2MessageCount)
};

console output

sock1 onmessageCount:1
sock2 onmessageCount:1
sock1 onmessageCount:2
sock2 onmessageCount:2
vlizard commented 9 years ago

@nicholasjstock I find console output in your example quite correct. All clients connected to the same server should receive the message that server sends into connection. You didn't specify the client you want to send you message to, so all of them receive it.

Ghirigoro commented 9 years ago

@vlizard The code that was posted is not broadcasting, so the output is not correct. Those messages are being sent to a specific socket (i.e. ws.send("msgSSS") is sending a message through ws, not to all clients).

colwilson commented 7 years ago

Here's a failing test around the broadcast example at https://github.com/websockets/ws#broadcast-example. It throws:

  1) Sockets broadcast:
     Uncaught TypeError: server.clients.forEach is not a function
      at Server.server.broadcast (test/test.js:22:20)
      at Server.<anonymous> (test/test.js:33:14)
      at node_modules/mock-socket/dist/webpack:/src/event-target.js:64:18
      at Array.forEach (native)
      at Server.dispatchEvent (node_modules/mock-socket/dist/webpack:/src/event-target.js:62:15)
      at WebSocket.delayCallback (node_modules/mock-socket/dist/webpack:/src/websocket.js:113:18)
      at Timeout._onTimeout (node_modules/mock-socket/dist/webpack:/src/helpers/delay.js:10:41)
import assert from 'assert'
import { WebSocket, Server } from 'mock-socket'

function Client () {
  const chatSocket = new WebSocket('ws://localhost:8080')
  this.messages = []

  chatSocket.onmessage = (event) => {
    this.messages.push(event.data)
  }
}

let server, client1, client2

beforeEach(() => {
  server = new Server('ws://localhost:8080')
  client1 = new Client()
  client2 = new Client()

  server.broadcast = (data) => {
    server.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(data)
      }
    })
  }
})

describe('Sockets', () => {
  it('broadcast', (done) => {
    server.on('connection', server => {
      server.broadcast('test message 1')
      server.broadcast('test message 2')
    })

    setTimeout(() => {
      assert.equal(client1.messages.length, 2, '2 messages passed')
      assert.equal(client2.messages.length, 2, '2 messages passed')
      server.stop(done)
    }, 100)
  })
})