Home>

I wondered if I could make a chat application with MAMP on an internal server with WebSocket + MAMP
I implemented it with reference to the article .

As for the in-house server, the M: area is allocated, and I access it by remote desktop connection to start MAMP and server.php.

Environment:
MAMP: 4.0.0.26869 * MAMP for windows
OS: Microsoft Windows [Version 6.3.9600]
Address to access M: sharem

As a result, if you open sharem/chat with multiple browsers on your own local desktop (not a shared server), you can confirm that the server connection is successful and the action (the comments are reflected). It was.

On the other hand, if Mr. B next to the same network accesses with the same address, the server connection will fail.
* By the way, MAMP on the M drive of the shared server works properly because it works if you open a file like echo "hello";in sharem/sample.html.

Similar to the following code, as in // here
It may be a problem with wsUri or host port, but
I asked a question without knowing why other clients could not connect properly even though WebSocket on the shared server works correctly in my local.

I would be happy if you could give me advice.
Thank you.

<? php
//index.php
$colors = array ('# 007AFF', '# FF7000', '# FF7000', '# 15E25F', '# CFC700', '# CFC700', '# CF1100', '# CF00BE', '# F00') ;
$color_pick = array_rand ($colors);
?>
<! DOCTYPE html>
<html>
<head>
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<style type = "text/css">
.chat-wrapper {
    font: bold 11px/normal 'lucida grande', tahoma, verdana, arial, sans-serif;
    background: # 00a6bb;
    padding: 20px;
    margin: 20px auto;
    box-shadow: 2px 2px 2px 0px # 00000017;
    max-width: 700px;
    min-width: 500px;
}
# message-box {
    width: 97%;
    display: inline-block;
    height: 300px;
    background: #fff;
    box-shadow: inset 0px 0px 2px # 00000017;
    overflow: auto;
    padding: 10px;
}
.user-panel {
    margin-top: 10px;
}
input [type = text] {
    border: none;
    padding: 5px 5px;
    box-shadow: 2px 2px 2px # 0000001c;
}
input [type = text] #name {
    width: 20%;
}
input [type = text] #message {
    width: 60%;
}
button # send-message {
    border: none;
    padding: 5px 15px;
    background: # 11e0fb;
    box-shadow: 2px 2px 2px # 0000001c;
}
</style>
</head>
<body>

<input type = "text" name = "name" placeholder = "your name" maxlength = "15" />
<input type = "text" name = "message" placeholder = "Please enter a message ..." maxlength = "100" />
<button>Send</button>


<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script language = "javascript" type = "text/javascript">
    // create a new WebSocket object.
    var msgBox = $('# message-box');
    var wsUri = "ws: // localhost: 9000/chat/server.php";// here
    websocket = new WebSocket (wsUri);
    websocket.onopen = function (ev) {// connection is open
        msgBox.append (' Server connection is successful "! ');// notify user
    }
    // Message received from server
    websocket.onmessage = function (ev) {
        var response = JSON.parse (ev.data);// PHP sends Json data
        var res_type = response.type;// message type
        var user_message = response.message;// message text
        var user_name = response.name;// user name
        var user_color = response.color;// color
        switch (res_type) {
            case 'usermsg':
                msgBox.append ('<span>' + user_name + '</span>:<span>' + user_message + '</span>');
                break;
            case 'system':
                msgBox.append ('' + user_message + '');
                break;
        }
        msgBox [0] .scrollTop = msgBox [0] .scrollHeight;// scroll message
    };
    websocket.onerror = function (ev) {msgBox.append (' Error Occurred-' + ev.data + '');};
    websocket.onclose = function (ev) {msgBox.append (' Connection Closed ');};
    // Message send button
    $('# send-message'). click (function () {
        send_message ();
    });
    // User hits enter key
    $("#message") .on ("keydown", function (event) {
      if (event.which == 13) {
          send_message ();
      }
    });
    // Send message
    function send_message () {
        var message_input = $('# message');// user message text
        var name_input = $('# name');// user name
        if (message_input.val () == "") {// empty name?
            alert ("Enter your Name please!");
            return;
        }
        if (message_input.val () == "") {// emtpy message?
            alert ("Enter Some message Please!");
            return;
        }
        // prepare json data
        var msg = {
            message: message_input.val (),
            name: name_input.val (),
            color: '<? php echo $colors [$color_pick];?>'
        };
        // convert and send data to server
        websocket.send (JSON.stringify (msg));
        message_input.val ('');// reset message input
    }</script>
</body>
</html>
<? php
//serever.php
$host = 'localhost';// host // here
$port = '9000';// port // here
$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, true);// 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 ($socket);
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));
}