Hello. I am developing a chat application loosely based on the ideas from Kost's cross server admin chat.
https://forums.alliedmods.net/showthread.php?t=29073
It appears that there is no way to watch a socket for new data, you must check if data exists, which is not inherently a problem.. however I am having an extremely hard time figuring out why this code is causing +20ms ping to all connected client (I expect a socket transport to cause some overhead on the server, but isnt that quite a bit for no data being sent?)
Anyways.. heres the code causing me my stress.
PHP Code:
public read_socket()
{
if(socket_is_readable(g_socket))
{
new buf[512];
new recv = socket_recv(g_socket, buf, charsmax(buf));
server_print("Readable: %d RECV: %d", 1, recv);
//server_print("SiR = %d", readable);
if(recv > 0)
{
//socket_recv(g_socket, buf, 512);
server_print(buf);
if (strlen(g_inbuffer) + strlen(buf) > 2560)
{
server_print("Error: Socket message overflow.");
disconnect_socket(1.0);
}
strcat(g_inbuffer, buf, charsmax(buf));
new pos = strfind(g_inbuffer, "^n");
while (pos!= -1)
{
new msg[512];
format(msg, pos, "%s", g_inbuffer);
if(msg[0]=='a')
{
//Authorize
if(msg[2]=='S')
{
//a.Success
//client_print(0, print_chat, "[ESN] Connected to master server!");
server_print("Authorized with master server.");
for(new i=0; i < get_maxplayers(); i++)
{
if(g_NeedsAuth[i])
{
AUTHORIZE(i);
g_NeedsAuth[i] = false;
}
}
}
}
if(msg[0]=='s')
{
//SYSTEM MSG
if(msg[1]=='.')
{
//c.Mesg (to all)
//client_print(0, print_chat, "%s", msg[2]);
copy(g_sockbuf[g_sbindex], MAX_MSG_BUF-1, msg);
g_sbindex++;
}
}
if(msg[0]=='p')
{
//pSTEAM_0:1:901100|SYSTEM|Mesg\n
server_print(msg);
copy(g_sockbuf[g_sbindex], MAX_MSG_BUF-1, msg);
server_print("%s", g_sockbuf[g_sbindex]);
g_sbindex++;
}
if( (msg[0]=='m') || (msg[0]=='c') )
{
//mSTEAM_0:1:901100|Hey Admins! What's up?\n
copy(g_sockbuf[g_sbindex], MAX_MSG_BUF-1, msg);
g_sbindex++;
}
format(g_inbuffer, charsmax(g_inbuffer), "%s", g_inbuffer[pos+1]);
pos = strfind(g_inbuffer, "^n");
}
//End of readable messages..
set_task(0.2, "read_socket");
server_print("Inbuffer Cleared.");
}
else
{
server_print("Socket error!");
disconnect_socket(3.0);
}
}
else set_task(0.5, "read_socket");
}
I don't *THINK* theres a more efficient way to poll a socket for a new message, the issue isnt even the data.. at most theres about 200-300 bytes sent down the stream once about every 2 seconds.. but I do want to be capable of handling up to 4+ messages a second as can be seen by the standard goldsrc chat protocol, but currently trying to set up a 0.5s manual looped task (set_task with flag "b" didn't give me much better results BTW) to read the data from the socket causes a +20ms ping, and that's only when there is one client connected.
I have heard that some people use entities instead of tasks, does this work better? or will I still see a big overhead like with the task system?
Any and all input is greatly appreciated. I have confirmed 100% that the lag is caused by this function as a whole, as disabling it will not increase my ping, and setting the delay higher seems to help subside the ping issue, however it still is present with 1.0s delay (which kind of defeats the purpose of a real time chat)
__________________