I'm trying to make socket io work in php using https://github.com/ElephantIO/elephant.io
I found an example from socket.io on how to setup the server. I can send messages to it but for some reason I can't get a reply to confirm sending message.
The logic of the server code is to create a room with a user name and then just send message to it.
Keep in mind that I can send messages from php side and I can receive users.
For some reason only private messages never get sent. I also have JS script implemented in browser that receives the messages just fine. Problem is I need confirmation in php and somehow it just doesn't happen.
server code
const Redis = require("ioredis");
const redisClient = new Redis(6379, "redis");
const io = require("socket.io")(httpServer, {
cors: {
origin: "http://localhost:8080",
},
adapter: require("socket.io-redis")({
pubClient: redisClient,
subClient: redisClient.duplicate(),
}),
});
const { setupWorker } = require("@socket.io/sticky");
const crypto = require("crypto");
const randomId = () => crypto.randomBytes(8).toString("hex");
const { RedisSessionStore } = require("./sessionStore");
const sessionStore = new RedisSessionStore(redisClient);
const { RedisMessageStore } = require("./messageStore");
const messageStore = new RedisMessageStore(redisClient);
io.use(async (socket, next) => {
const sessionID = socket.handshake.auth.sessionID;
if (sessionID) {
const session = await sessionStore.findSession(sessionID);
if (session) {
socket.sessionID = sessionID;
socket.userID = session.userID;
socket.username = session.username;
return next();
}
}
const username = socket.handshake.auth.username;
if (!username) {
return next(new Error("invalid username"));
}
socket.sessionID = randomId();
socket.userID = randomId();
socket.username = username;
next();
});
io.on("connection", async (socket) => {
// persist session
sessionStore.saveSession(socket.sessionID, {
userID: socket.userID,
username: socket.username,
connected: true,
});
// emit session details
socket.emit("session", {
sessionID: socket.sessionID,
userID: socket.userID,
});
// join the "userID" room
socket.join(socket.username);
console.log(socket.rooms);
// fetch existing users
const users = [];
const [messages, sessions] = await Promise.all([
messageStore.findMessagesForUser(socket.userID),
sessionStore.findAllSessions(),
// sessionStore.deleteAllSessions(),
]);
const messagesPerUser = new Map();
messages.forEach((message) => {
const { from, to } = message;
const otherUser = socket.userID === from ? to : from;
if (messagesPerUser.has(otherUser)) {
messagesPerUser.get(otherUser).push(message);
} else {
messagesPerUser.set(otherUser, [message]);
}
});
sessions.forEach((session) => {
users.push({
userID: session.userID,
username: session.username,
connected: session.connected,
messages: messagesPerUser.get(session.userID) || [],
});
});
socket.emit("users", users);
// notify existing users
socket.broadcast.emit("user connected", {
userID: socket.userID,
username: socket.username,
connected: true,
messages: [],
});
// forward the private message to the right recipient (and to other tabs of the sender)
socket.on("private message", ({ content, to }) => {
content = content.replace(/\\r\\n/g, '\r\n');
const message = {
content,
from: socket.username,
to,
};
console.log(message);
socket.to(to).to('test').to(socket.userID).to('WhfrlTOl6-CfbfOKAAAB').emit("private message", message);
console.log(socket.userID);
// messageStore.saveMessage(message);
});
// notify users upon disconnection
socket.on("disconnect", async () => {
const matchingSockets = await io.in(socket.userID).allSockets();
const isDisconnected = matchingSockets.size === 0;
if (isDisconnected) {
// notify other users
socket.broadcast.emit("user disconnected", socket.userID);
// update the connection status of the session
sessionStore.saveSession(socket.sessionID, {
userID: socket.userID,
username: socket.username,
connected: false,
});
}
});
});
setupWorker(io);
client
$namespace = NULL;
$event = 'private message';
// Only enable polling transport.
$client = setup_client($namespace, NULL, ['transports' => 'polling', 'auth' => ['username' => 'test']]);
$client->emit($event, ['content' => '$this->message 1', 'to' => 'admin']);
if ($retval = $client->wait($event)) {
echo sprintf("Got a reply for first message:");
}
$client->emit($event, ['content' => '$this->message 2', 'to' => 'admin']);
if ($retval = $client->wait($event)) {
echo sprintf("Got a reply for second message:");
}
$client->disconnect();
EDIT: Upon further testing, problem seems to be with rooms. If I just emit message to everyone it arrives.