是否有任何教程或指南显示如何用PHP编写一个简单的Websockets服务器?我曾尝试在Google上寻找它,但没有找到很多。我找到了phpwebsockets,但是现在已经过时了,不支持最新的协议。我尝试自己更新它,但似乎不起作用。
#!/php -q
<?php /* >php -q server.php */
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$master = WebSocket("localhost",12345);
$sockets = array($master);
$users = array();
$debug = false;
while(true){
$changed = $sockets;
socket_select($changed,$write=NULL,$except=NULL,NULL);
foreach($changed as $socket){
if($socket==$master){
$client=socket_accept($master);
if($client<0){ console("socket_accept() failed"); continue; }
else{ connect($client); }
}
else{
$bytes = @socket_recv($socket,$buffer,2048,0);
if($bytes==0){ disconnect($socket); }
else{
$user = getuserbysocket($socket);
if(!$user->handshake){ dohandshake($user,$buffer); }
else{ process($user,$buffer); }
}
}
}
}
//---------------------------------------------------------------
function process($user,$msg){
$action = unwrap($msg);
say("< ".$action);
switch($action){
case "hello" : send($user->socket,"hello human"); break;
case "hi" : send($user->socket,"zup human"); break;
case "name" : send($user->socket,"my name is Multivac, silly I know"); break;
case "age" : send($user->socket,"I am older than time itself"); break;
case "date" : send($user->socket,"today is ".date("Y.m.d")); break;
case "time" : send($user->socket,"server time is ".date("H:i:s")); break;
case "thanks": send($user->socket,"you're welcome"); break;
case "bye" : send($user->socket,"bye"); break;
default : send($user->socket,$action." not understood"); break;
}
}
function send($client,$msg){
say("> ".$msg);
$msg = wrap($msg);
socket_write($client,$msg,strlen($msg));
}
function WebSocket($address,$port){
$master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed");
socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed");
socket_bind($master, $address, $port) or die("socket_bind() failed");
socket_listen($master,20) or die("socket_listen() failed");
echo "Server Started : ".date('Y-m-d H:i:s')."\n";
echo "Master socket : ".$master."\n";
echo "Listening on : ".$address." port ".$port."\n\n";
return $master;
}
function connect($socket){
global $sockets,$users;
$user = new User();
$user->id = uniqid();
$user->socket = $socket;
array_push($users,$user);
array_push($sockets,$socket);
console($socket." CONNECTED!");
}
function disconnect($socket){
global $sockets,$users;
$found=null;
$n=count($users);
for($i=0;$i<$n;$i++){
if($users[$i]->socket==$socket){ $found=$i; break; }
}
if(!is_null($found)){ array_splice($users,$found,1); }
$index = array_search($socket,$sockets);
socket_close($socket);
console($socket." DISCONNECTED!");
if($index>=0){ array_splice($sockets,$index,1); }
}
function dohandshake($user,$buffer){
console("\nRequesting handshake...");
console($buffer);
//list($resource,$host,$origin,$strkey1,$strkey2,$data)
list($resource,$host,$u,$c,$key,$protocol,$version,$origin,$data) = getheaders($buffer);
console("Handshaking...");
$acceptkey = base64_encode(sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
$upgrade = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: $acceptkey\r\n";
socket_write($user->socket,$upgrade,strlen($upgrade));
$user->handshake=true;
console($upgrade);
console("Done handshaking...");
return true;
}
function getheaders($req){
$r=$h=$u=$c=$key=$protocol=$version=$o=$data=null;
if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; }
if(preg_match("/Host: (.*)\r\n/" ,$req,$match)){ $h=$match[1]; }
if(preg_match("/Upgrade: (.*)\r\n/",$req,$match)){ $u=$match[1]; }
if(preg_match("/Connection: (.*)\r\n/",$req,$match)){ $c=$match[1]; }
if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$req,$match)){ $key=$match[1]; }
if(preg_match("/Sec-WebSocket-Protocol: (.*)\r\n/",$req,$match)){ $protocol=$match[1]; }
if(preg_match("/Sec-WebSocket-Version: (.*)\r\n/",$req,$match)){ $version=$match[1]; }
if(preg_match("/Origin: (.*)\r\n/",$req,$match)){ $o=$match[1]; }
if(preg_match("/\r\n(.*?)\$/",$req,$match)){ $data=$match[1]; }
return array($r,$h,$u,$c,$key,$protocol,$version,$o,$data);
}
function getuserbysocket($socket){
global $users;
$found=null;
foreach($users as $user){
if($user->socket==$socket){ $found=$user; break; }
}
return $found;
}
function say($msg=""){ echo $msg."\n"; }
function wrap($msg=""){ return chr(0).$msg.chr(255); }
function unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); }
function console($msg=""){ global $debug; if($debug){ echo $msg."\n"; } }
class User{
var $id;
var $socket;
var $handshake;
}
?>
和客户:
var connection = new WebSocket('ws://localhost:12345');
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
};
如果我的代码有任何错误,您可以帮我解决它吗?Firefox中的Concole说Firefox can't establish a connection to the server at ws://localhost:12345/.
我和您最近在同一条船上,这是我的工作:
1)我使用phpwebsockets代码作为如何构建服务器端代码的参考。(您似乎已经在执行此操作,并且正如您所指出的,由于多种原因,该代码实际上并不起作用。)
2)我使用PHP.net阅读有关phpwebsockets代码中使用的每个套接字函数的详细信息。通过这样做,我终于能够理解整个系统在概念上是如何工作的。这是一个很大的障碍。
3)我阅读了实际的WebSocket草案(请对其进行网络搜索,因为每个帖子不能发布两个以上的链接)。在开始深入研究之前,我不得不阅读了很多次。在整个过程中,您可能不得不一次又一次地回到本文档,因为它是拥有正确,最新信息的权威资源。有关WebSocket
API的信息。
4)我根据#3草案中的说明对正确的握手过程进行了编码。这还不错。
5)握手后,我一直收到从客户端发送到服务器的一堆乱码,直到我意识到数据已被编码并且必须被屏蔽后,我才能弄清楚为什么。以下链接在这里对我有很大帮助:
请注意,此链接上的可用代码存在许多问题,如果不做进一步修改,将无法正常工作。
6)然后,我遇到了以下SO线程,该线程清楚地说明了如何正确地编码和解码来回发送的消息:如何在服务器端发送和接收WebSocket消息?
这个链接真的很有帮助。我建议在查看WebSocket草案时咨询它。它将有助于使草案中的内容更有意义。
7)至此我几乎完成了工作,但是使用WebSocket开发的WebRTC应用程序出现了一些问题,因此我最终在SO上问了自己一个问题,最终我解决了。要参考问题和答案,请在网络上搜索“
SORTC候选人信息末尾的这些数据是什么?” (不带引号)。
8)至此,我几乎可以正常工作了。我只需要添加一些其他逻辑来处理连接的关闭,就完成了。
这个过程总共花了我大约两个星期。好消息是,我现在非常了解WebSocket,并且能够从头开始制作自己的客户端和服务器脚本,效果很好。希望所有这些信息的总汇能够为您提供足够的指导和信息,以编写您自己的WebSocket
PHP脚本。祝好运!
编辑#2
:虽然我仍然喜欢使用PHP来完成许多服务器端相关的工作,但我不得不承认我最近确实很热身使用Node.js,主要原因是因为它的设计更好。比PHP(或任何其他服务器端语言)更能处理WebSocket。因此,我最近发现,在服务器上设置Apache/ PHP和Node.js并使用Node.js运行WebSocket服务器以及使用Apache/PHP进行其他操作要容易得多。在无法安装/使用Node.js forWebSocket的共享托管环境中,您可以使用Heroku等免费服务来设置Node.jsWebSocket服务器并进行跨域从您的服务器请求它。
问题内容: 我正在使用node.js的WSwebsocket库。目前,我正在运行ws服务器。现在,我想通过使用安全连接(即通过实施wss协议以及库支持TLS连接)来保护此连接。我进行了一些搜索,发现这很容易确保安全:wss和具有自签名证书的wss。 两者都不是很详细,第二个链接上的文章介绍了带有自签名证书的wss。我想知道的是,仅创建自签名证书并部署到我的生产环境是否就足够了?还是我需要像创建HT
我试图用php执行nodejs,这样做非常简单 我的nodejs文件创建了一个带有Express的服务器。 当文件运行时,这就是输出 错误:侦听EACCES 127.0。0.1:82 bject.exports._errnoException(util.js:873: 11) 在出口方面_主机端口例外(util.js:896:20) 在服务器上_listen2(net.js:1237:19) 听(
问题内容: 我讨厌问这样一个模糊的问题,但是我很难找到一个简单的例子。这是我到目前为止的内容: 我可以找到的嵌入式Jetty示例始终显示如下内容,以启动运行的Server实例,但我不知道如何实例化WebSocketServlet。 如何创建可以处理WebSocket连接请求的嵌入式服务器? 问题答案: 更新:2013年12月2日 有关带有WebSocket的嵌入式码头的最新示例,请参见: http
问题内容: 给定一个SSL密钥和证书,如何创建HTTPS服务? 问题答案: 我发现以下示例。 这适用于节点v0.1.94-v0.3.1。在新版本的节点中被删除。 直接从该来源:
我在eclipse中创建了一个新服务器,但后来由于某种原因删除了它,现在我无法创建一个新服务器。我得到了Apache Tomcat7,但是当我从列表中选择Tomcat v7服务器时,服务器名称字段是不可编辑的,而且按钮也不工作(完成,下一步)。