Javascript客户端如何连接到PHp套接字服务器


How can Javascript client connect to PHp socket Server?

嗨,我有一个用PHP编写的运行套接字服务器。

服务器正在监听连接。任何想法如何我的客户端(写在javascript)将连接到服务器和发送数据给它?

PS:我只知道如何连接php客户端到套接字服务器,但不知道如何连接javascript客户端。

感谢大家的宝贵时间。

我使用标准的WebSocket客户端API。核心PHP套接字用于服务器端。

知道,在浏览器上使用websocket发送和接收数据头。但是PHP套接字的代码,发送和接收没有头,只是发送普通数据。

所以我们需要在socket服务器端模拟报头。

为了学习和知道如何做到这一点,我写了这个清晰的示例代码,用这个代码你可以发送一个短语到服务器,并在客户端接收反向短语。

server.php

<?php
//Code by: Nabi KAZ <www.nabi.ir>
// set some variables
$host = "127.0.0.1";
$port = 5353;
// don't timeout!
set_time_limit(0);
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0)or die("Could not create socket'n");
// bind socket to port
$result = socket_bind($socket, $host, $port)or die("Could not bind to socket'n");
// start listening for connections
$result = socket_listen($socket, 20)or die("Could not set up socket listener'n");
$flag_handshake = false;
$client = null;
do {
    if (!$client) {
        // accept incoming connections
        // client another socket to handle communication
        $client = socket_accept($socket)or die("Could not accept incoming connection'n");
    }
    $bytes =  @socket_recv($client, $data, 2048, 0);
    if ($flag_handshake == false) {
        if ((int)$bytes == 0)
            continue;
        //print("Handshaking headers from client: ".$data."'n");
        if (handshake($client, $data, $socket)) {
            $flag_handshake = true;
        }
    }
    elseif($flag_handshake == true) {
        if ($data != "") {
            $decoded_data = unmask($data);
            print("< ".$decoded_data."'n");
            $response = strrev($decoded_data);
            socket_write($client, encode($response));
            print("> ".$response."'n");
            socket_close($client);
            $client = null;
            $flag_handshake = false;
        }
    }
} while (true);
// close sockets
socket_close($client);
socket_close($socket);
function handshake($client, $headers, $socket) {
    if (preg_match("/Sec-WebSocket-Version: (.*)'r'n/", $headers, $match))
        $version = $match[1];
    else {
        print("The client doesn't support WebSocket");
        return false;
    }
    if ($version == 13) {
        // Extract header variables
        if (preg_match("/GET (.*) HTTP/", $headers, $match))
            $root = $match[1];
        if (preg_match("/Host: (.*)'r'n/", $headers, $match))
            $host = $match[1];
        if (preg_match("/Origin: (.*)'r'n/", $headers, $match))
            $origin = $match[1];
        if (preg_match("/Sec-WebSocket-Key: (.*)'r'n/", $headers, $match))
            $key = $match[1];
        $acceptKey = $key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
        $acceptKey = base64_encode(sha1($acceptKey, true));
        $upgrade = "HTTP/1.1 101 Switching Protocols'r'n".
            "Upgrade: websocket'r'n".
            "Connection: Upgrade'r'n".
            "Sec-WebSocket-Accept: $acceptKey".
            "'r'n'r'n";
        socket_write($client, $upgrade);
        return true;
    } else {
        print("WebSocket version 13 required (the client supports version {$version})");
        return false;
    }
}
function unmask($payload) {
    $length = ord($payload[1]) & 127;
    if ($length == 126) {
        $masks = substr($payload, 4, 4);
        $data = substr($payload, 8);
    }
    elseif($length == 127) {
        $masks = substr($payload, 10, 4);
        $data = substr($payload, 14);
    }
    else {
        $masks = substr($payload, 2, 4);
        $data = substr($payload, 6);
    }
    $text = '';
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i % 4];
    }
    return $text;
}
function encode($text) {
    // 0x1 text frame (FIN + opcode)
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);
    if ($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)$header = pack('CCS', $b1, 126, $length);
    elseif($length >= 65536)
    $header = pack('CCN', $b1, 127, $length);
    return $header.$text;
}

client.htm

<html>
<script>
//Code by: Nabi KAZ <www.nabi.ir>
var socket = new WebSocket('ws://localhost:5353');
// Open the socket
socket.onopen = function(event) {
    var msg = 'I am the client.';
    console.log('> ' + msg);
    // Send an initial message
    socket.send(msg);
    // Listen for messages
    socket.onmessage = function(event) {
        console.log('< ' + event.data);
    };
    // Listen for socket closes
    socket.onclose = function(event) {
        console.log('Client notified socket has closed', event);
    };
    // To close the socket....
    //socket.close()
};
</script>
<body>
<p>Please check the console log of your browser.</p>
</body>
</html>

手动操作:先在命令行上运行php server.php,然后在浏览器上打开http://localhost/client.htm

你可以看到结果:

http://localhost/client.htm
> I am the client.
< .tneilc eht ma I
php server.php
< I am the client.
> .tneilc eht ma I

请注意,这只是一个测试发送和接收数据的示例代码,对于执行工作没有用处。

我建议你使用这些项目:

https://github.com/ghedipunk/PHP-Websockets
https://github.com/esromneb/phpwebsocket
https://github.com/acbrandao/PHP/tree/master/ws
https://github.com/srchea/PHP-Push-WebSocket/
http://socketo.me/

我还建议你阅读这些文章以了解更多细节:

http://www.abrandao.com/2013/06/websockets-html5-php/
http://cuelogic.com/blog/php-and-html5-websocket-server-and-client-communication/
http://srchea.com/build-a-real-time-application-using-html5-websockets

回答一个老问题,以防人们像我一样通过谷歌找到它。

现在几乎所有的当代浏览器都支持WebSocket Javascript API。通过WS,浏览器中的客户端JS可以向用PHP或其他语言编写的服务器打开全双工套接字。服务器必须实现WS协议,但是现在有针对PHP、Java和其他语言的WS库。

在写这篇文章的时候,WS的实现看起来仍然有点像一个移动的目标,但是,我目前正在使用WS/JS浏览器客户端与WS/Java服务器通信,它似乎正在工作。

建议用您选择的服务器语言搜索WS实现。

希望这对你有帮助!

我不知道有什么东西可以为JS提供任意套接字功能。对Web Sockets的支持有限(我认为这需要您修改服务器以符合空间)。如果做不到这一点,简单的XHR可能会满足您的需求(这将要求您修改服务器以充当web服务)。如果服务运行在与页面不同的原点上,那么您将需要使用CORS或使用诸如JSONP之类的变通方法。

试试这个:

http://code.google.com/p/phpwebsocket/

简单地说——你不能这么做——让客户端代码打开套接字连接是一个安全漏洞。

但是,您可以模拟-将数据作为AJAX请求发送到另一个PHP页面,然后使该PHP页面通过套接字进行通信。

更新2017

:

与此同时,websockets成为了一种东西。请注意,websocket协议与一般的网络套接字是不同的