Open bahmanbs opened 2 years ago
Can you show more reproduction code? I'm not familiar with regex dynamic namespaces, but from a cursory read of the code I don't see a way that creating the publish channel would be dependent on the namespace name.
client side code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js" integrity="sha384-/KNQL8Nu5gCHLqwqfQjA689Hhoqgi2S84SNUxC3roTe4EhJ9AfLkp8QiQcU8AMzI" crossorigin="anonymous"></script>
<script>
const io_1 = io(`http://localhost:3000/test-123`);
const io_2 = io(`http://localhost:3000/test-456`);
io_1.on("connection-established", (namespaceName) => console.log(`you are connected to the ${ namespaceName } namespace`));
io_2.on("connection-established", (namespaceName) => console.log(`you are connected to the ${ namespaceName } namespace`));
</script>
</body>
</html>
server side code
const { Server } = require('socket.io');
const io = new Server(3000);
// ----- amqp adapter does not work on dynamic naaspaces -----
const { createAdapter } = require('socket.io-amqp0');
const { connect } = require('amqplib');
io.adapter(createAdapter({ amqpConnection: () => connect('amqp://localhost') }));
// ----- redis adapter works on dynamic namespaces -----
// const { createAdapter } = require("@socket.io/redis-adapter");
// const { createClient } = require("redis");
// const pubClient = createClient({ url: "redis://localhost:6379" });
// const subClient = pubClient.duplicate();
// io.adapter(createAdapter(pubClient, subClient));
/**
* the namespace here could be dynamic like so.
* this means client can connect to socket server with a dynamic format
* for example:
* io("http://localhost:3000/[namespace]")
* in our example it could be:
* io("http://localhost:3000/test-abc123") OR io("http://localhost:3000/test-xyz789")
*
* THIS IS SUPPORTED BY REDIS ADAPTER AND IT WORKS
*/
io.of(/^\/test-\w+$/).on("connection", (socket) => {
const namespaceName = socket.nsp.name;
socket.emit("connection-established", namespaceName);
});
console.log("server is running on port 3000")
just run rabbitmq or redis and uncomment related code to see what happens on successful connection, in console we can see name of namespaces
for more info about dynamic namespaces read this link on socket.io documentation
when using dynamic namespaces (using regex), amqp adapter throws an error in line 167 of index.ts
this.publishChannel.assertExchange(this.exchangeName, 'direct', { autoDelete: true, durable: false });
it says can access
assertExchange
ofundfined
After checking the code a bit, I realized that when connecting the client to the socket server with different namespaces, the client tries to communicate with the
/
namespace and this causes an error. In case I did not intend to connect to the/
namespace. The problem was solved by placing the two methodscreateRoomExchangeAndQueue
andcreateRoomListener
inside thetry/catch
block