0

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.

0

Browse other questions tagged or ask your own question.