2

I currently have the following scripts:

Chat.php

<?php
require_once 'core/Init.php';
$user = new User();    
$colours = array('007AFF','FF7000','FF7000','15E25F','CFC700','CFC700','CF1100','CF00BE','F00');
$user_colour = array_rand($colours);
?>
<script language="javascript" type="text/javascript">
    $(document).ready(function(){
        //create a new WebSocket object.
        var wsUri = "ws://199.188.203.97:9000/includes/server.php";
        websocket = new WebSocket(wsUri);

        websocket.onopen = function(ev) { // connection is open
            $('#message_box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
        }

        $('#chatform').submit(function(event){ //if user clicks message send button
            event.preventDefault();
            var mymessage = $('#message').val(); //get message text
            var myname = '<?php echo $user->data()->username; ?>'; //get user name

            if(mymessage == ""){ //emtpy message?
                alert("Enter Some message Please!");
                return;
            }

            //prepare json data
            var msg = {
                message: mymessage,
                name: myname,
                color : '<?php echo $colours[$user_colour]; ?>'
            };
            //convert and send data to server
            websocket.send(JSON.stringify(msg));
        });

        //#### Message received from server?
        websocket.onmessage = function(ev) {
            var msg = JSON.parse(ev.data); //PHP sends Json data
            var type = msg.type; //message type
            var umsg = msg.message; //message text
            var uname = msg.name; //user name
            var ucolor = msg.color; //color

            if(type == 'usermsg')
            {
                $('#message_box').append("<div><span class=\"user_name\" style=\"color:#"+ucolor+"\">"+uname+"</span> : <span class=\"user_message\">"+umsg+"</span></div>");
            }
            if(type == 'system')
            {
                $('#message_box').append("<div class=\"system_msg\">"+umsg+"</div>");
            }

            $('#message').val(''); //reset text
        };

        websocket.onerror   = function(ev){$('#message_box').append("<div class=\"system_error\">Error Occurred - "+ev.data+"</div>");};
        websocket.onclose   = function(ev){$('#message_box').append("<div class=\"system_msg\">Connection Closed</div>");};
    });
</script>
<div id="chat" class="fixed" data-current-user="<?php echo $user->data()->username; ?>" data-order-by-status="1" data-max-chat-history="25">

    <!-- conversation template -->
    <div class="chat-outer">
        <div class="message_box" id="message_box" style="background-color: #fff;padding: 10px;margin-bottom: 10px;margin-left: 10px;height: 90%;"></div>
        <form id="chatform">
            <input type="text" name="message" id="message" placeholder="Message" maxlength="80" autocomplete="off" style="width: 95%;margin-left: 10px;padding: 2px;" />
            <input type="submit" class="btn btn-info" value="Send">
        </form>
    </div>
    <div id="chatinner">
        <?php include("chatInner.php"); ?>
    </div>
</div>
</div>
</div>

and Server.php

<?php


$host = 'localhost'; //host
$port = '9000'; //port
$null = NULL; //null var

//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

//bind socket to specified host
socket_bind($socket, 0, $port);

//listen to port
socket_listen($socket);

//create & add listning socket to the list
$clients = array($socket);

//start endless loop, so that our script doesn't stop
while (true) {
    //manage multipal connections
    $changed = $clients;
    //returns the socket resources in $changed array
    socket_select($changed, $null, $null, 0, 10);

    //check for new socket
    if (in_array($socket, $changed)) {
        $socket_new = socket_accept($socket); //accpet new socket
        $clients[] = $socket_new; //add socket to client array

        $header = socket_read($socket_new, 1024); //read data sent by the socket
        perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake

        socket_getpeername($socket_new, $ip); //get ip address of connected socket
        $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); //prepare json data
        send_message($response); //notify all users about new connection

        //make room for new socket
        $found_socket = array_search($socket, $changed);
        unset($changed[$found_socket]);
    }

    //loop through all connected sockets
    foreach ($changed as $changed_socket) { 

        //check for any incomming data
        while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
        {
            $received_text = unmask($buf); //unmask data
            $tst_msg = json_decode($received_text); //json decode 
            $user_name = $tst_msg->name; //sender name
            $user_message = $tst_msg->message; //message text
            $user_color = $tst_msg->color; //color

            //prepare data to be sent to client
            $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));
            send_message($response_text); //send data
            break 2; //exist this loop
        }

        $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
        if ($buf === false) { // check disconnected client
            // remove client for $clients array
            $found_socket = array_search($changed_socket, $clients);
            socket_getpeername($changed_socket, $ip);
            unset($clients[$found_socket]);

            //notify all users about disconnected connection
            $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));
            send_message($response);
        }
    }
}
// close the listening socket
socket_close($sock);

function send_message($msg)
{
    global $clients;
    foreach($clients as $changed_socket)
    {
        @socket_write($changed_socket,$msg,strlen($msg));
    }
    return true;
}


//Unmask incoming framed message
function unmask($text) {
    $length = ord($text[1]) & 127;
    if($length == 126) {
        $masks = substr($text, 4, 4);
        $data = substr($text, 8);
    }
    elseif($length == 127) {
        $masks = substr($text, 10, 4);
        $data = substr($text, 14);
    }
    else {
        $masks = substr($text, 2, 4);
        $data = substr($text, 6);
    }
    $text = "";
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i%4];
    }
    return $text;
}

//Encode message for transfer to client.
function mask($text)
{
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);

    if($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)
        $header = pack('CCn', $b1, 126, $length);
    elseif($length >= 65536)
        $header = pack('CCNN', $b1, 127, $length);
    return $header.$text;
}

//handshake new client.
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
    $headers = array();
    $lines = preg_split("/\r\n/", $receved_header);
    foreach($lines as $line)
    {
        $line = chop($line);
        if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
        {
            $headers[$matches[1]] = $matches[2];
        }
    }

    $secKey = $headers['Sec-WebSocket-Key'];
    $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
    //hand shaking header
    $upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
    "Upgrade: websocket\r\n" .
    "Connection: Upgrade\r\n" .
    "WebSocket-Origin: $host\r\n" .
    "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
    "Sec-WebSocket-Accept:$secAccept\r\n\r\n";
    socket_write($client_conn,$upgrade,strlen($upgrade));
}

Everything works fine but what I would like to do is have the username send to the server so if someone connects, it shows their username instead of the IP. Just wondering how I would go about doing this. Thanks in advance!

1 Answer 1

3

If you're using other peoples script, it's always good practice to reference where you found it :D ...

Ref: http://www.sanwebe.com/2013/05/chat-using-websocket-php-socket

I've been playing around with this script aswell, it's really good :D

So, onto what I hope will answer your question ...

What you could do, is send the username in the websocket.onopen function (Formated so that the server can understand when a new username is being sent), and then alter the server.php code to then notify everyone of the new user ... So it would look something like this:

Chat.php changes

    websocket.onopen = function(ev) {
        $('#message_box').append("<div class=\"system_msg\">Connected!</div>");
        //send username to server
        var msg = {
            newuser: '<?php echo $user->data()->username; ?>' 
        };
        websocket.send(JSON.stringify(msg));
    }

Server.php changes

if (in_array($socket, $changed)) {
    $socket_new = socket_accept($socket);
    $clients[] = $socket_new;

    $header = socket_read($socket_new, 1024);
    perform_handshaking($header, $socket_new, $host, $port);

    //remove the code that sends the IP
    //socket_getpeername($socket_new, $ip);
    //$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected')));
    //send_message($response);

    $found_socket = array_search($socket, $changed);
    unset($changed[$found_socket]);
}

..

foreach ($changed as $changed_socket) { 

    while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
    {
        $received_text = unmask($buf);
        $tst_msg = json_decode($received_text);
        //check if the 'newuser' has been recieved, otherwise send a normal message
        if(isset($tst_msg->newuser)) {
            $response = mask(json_encode(array('type'=>'system', 'message'=>$tst_msg.' joined the room')));
            send_message($response);
        } else {
            $user_name = $tst_msg->name;
            $user_message = $tst_msg->message;
            $user_color = $tst_msg->color;

            $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));
            send_message($response_text);
        }

        break 2;
    }

Hope this helps :D

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.