问题描述
我正在尝试在服务器上使用websocket。问题似乎是我的证书,但错误消息显示PHP正在搜索我未指定的文件。直接在下面的是下面进一步给出的代码的输出。请参考https://www.php.net/manual/en/context.ssl.php进行参考。
8888
WSS
Context Created
stream_socket_server Created
....1,stream would like to be processed.
PHP Warning: stream_socket_accept(): Unable to set private key file '/etc/letsencrypt/archive/example.org/fullchain1.pem' in /var/www/carbonPHP.com/server.PHP on line 108
PHP Warning: stream_socket_accept(): Failed to enable crypto in /var/www/example.com/server.PHP on line 108
PHP Warning: stream_socket_accept(): accept Failed: Success in /var/www/example.com/server.PHP on line 108
stream_socket_accept Failed
我正在查看以上文档,并尝试了许多不同的配置组合。查看上面的代码和输出,我看到它正在搜索'fullchain1.pem',但是我为 stream_context_create 提供了'fullchain.pem'。当用户实际连接时,它不会被使用并在 stream_select 之前发出警告。 Safari实际上为我提供了错误消息 WebSocket网络错误:Osstatus错误-9806 的详细信息。这是一个通用的连接错误,因为PHP失败了。我使用let-encrypt生成密钥文件,并进行了一些探索,使我进入了该文件夹。我已经尝试了所有文件,但没有一个起作用。
root@blackhat:/etc/letsencrypt/live/example.org# ls
README cert.pem chain.pem fullchain.pem fullchain1.pem privkey.pem
root@blackhat:/etc/letsencrypt/live/example.org# rm fullchain1.pem
root@blackhat:/etc/letsencrypt/live/example.org# cat README
This directory contains your keys and certificates.
`privkey.pem` : the private key for your certificate.
`fullchain.pem`: the certificate file used in most server software.
`chain.pem` : used for OCSP stapling in Nginx >=1.3.7.
`cert.pem` : will break many server configurations,and should not be used
without reading further documentation (see link below).
移至代码。 *请知道SSL已关闭,该服务才能在tcp上正确运行。
/server.PHP
#!/usr/bin/PHP
<?PHP
const TEXT = 0x1;
const BINARY = 0x2;
const CLOSE = 0x8;
const PING = 0x9;
const PONG = 0xa;
const HOST = '0.0.0.0';
const PORT = 8888;
const SSL = true;
const CERT = '/etc/letsencrypt/live/example.org/fullchain.pem';
const PASS = '';
print PORT . PHP_EOL . (SSL ? 'WSS' : 'WS') . PHP_EOL;
if (SSL) {
//SSLCertificateFile /etc/letsencrypt/live/example.org/fullchain.pem
//SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem
$context = stream_context_create([
'ssl' => [
//'cafile' => __DIR__ . DIRECTORY_SEParaTOR . 'certificate.crt','local_cert' => CERT,//'peer_fingerprint' => PEER_FINGERPRINT,'CURLOPT_VERBOSE' => true,'verify_peer' => true,'verify_peer_name' => false,'allow_self_signed' => false,'verify_depth' => 5,//'CN_match' => 'carbonPHP.com','disable_compression' => true,'SNI_enabled' => true,'ciphers' => 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK'
]
]);
print 'Context Created' . PHP_EOL;
$protocol = 'ssl';
} else {
$context = stream_context_create();
$protocol = 'tcp';
}
$socket = stream_socket_server("$protocol://" . HOST . ':' . PORT,$errorNumber,$errorString,STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,$context);
print 'stream_socket_server Created' . PHP_EOL;
if (!$socket) {
echo "$errorString ($errorNumber)<br />\n";
} else {
$master[] = $socket;
while (true) {
$read = $master;
$mod_fd = stream_select($read,$_w,$_e,5); // returns number of file descriptors modified
if ($mod_fd === 0) {
print '.';
continue;
}
print "$mod_fd,stream would like to be processed.\n\n";
foreach ($read as $connection) {
if ($connection === $socket) { // accepting a new connection?
$conn = stream_socket_accept($socket);
if (false === $conn) {
print "stream_socket_accept Failed\n";
continue;
}
if (!handshake($conn)) {
fclose($conn);
continue;
}
fwrite($conn,encode('Hello! The time is ' . date('n/j/Y g:i a') . "\n"));
$master[] = $conn;
continue;
}
$data = decode($connection);
switch ($data['opcode']) {
case CLOSE:
$key_to_del = array_search($connection,$master,false);
@fclose($connection);
unset($master[$key_to_del]);
break;
case PING :
@fwrite($connection,encode('',PONG));
break;
case TEXT:
print $data['payload']->name . ',has sent :: ' . $data['payload']->message . PHP_EOL;
foreach ($master as $user) {
// connection === $user and continue; // but we dont hav this optimization on the front end
@fwrite($user,encode([
'type' => 'usermsg','name' => $data['payload']->name,'message' => $data['payload']->message,'color' => $data['payload']->color
]));
}
break;
default:
break;
}
}
}
}
function handshake($socket): bool
{
$headers = [];
$lines = preg_split("/\r\n/",@fread($socket,4096));
foreach ($lines as $line) {
$line = rtrim($line);
if (preg_match('/\A(\S+): (.*)\z/',$line,$matches)) {
$headers[$matches[1]] = $matches[2];
}
}
if (!isset($headers['Sec-WebSocket-Key'])) {
return false;
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*',sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$response = "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: wss://" . HOST . ":" . PORT . "/\r\n" .
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
try {
return fwrite($socket,$response);
} catch (Exception $e) {
return false;
}
}
function encode($message,$opCode = TEXT): string
{
$rsv1 = 0x0;
$rsv2 = 0x0;
$rsv3 = 0x0;
$message = json_encode($message);
$length = strlen($message);
$out = chr((0x1 << 7) | ($rsv1 << 6) | ($rsv2 << 5) | ($rsv3 << 4) | $opCode);
if (0xffff < $length) {
$out .= chr(0x7f) . pack('NN',$length);
} elseif (0x7d < $length) {
$out .= chr(0x7e) . pack('n',$length);
} else {
$out .= chr($length);
}
return $out . $message;
}
function decode($socket): array
{
if (!$socket || !is_resource($socket)) {
return [
'opcode' => CLOSE,'payload' => ''
];
}
$out = [];
$read = @fread($socket,1);
if (empty($read)) {
return [
'opcode' => CLOSE,'payload' => ''
];
}
$handle = ord($read);
$out['fin'] = ($handle >> 7) & 0x1;
$out['rsv1'] = ($handle >> 6) & 0x1;
$out['rsv2'] = ($handle >> 5) & 0x1;
$out['rsv3'] = ($handle >> 4) & 0x1;
$out['opcode'] = $handle & 0xf;
if (!\in_array($out['opcode'],[TEXT,BINARY,CLOSE,PING,PONG],true)) {
return [
'opcode' => '','payload' => '','error' => 'unkNown opcode (1003)'
];
}
$handle = ord(fread($socket,1));
$out['mask'] = ($handle >> 7) & 0x1;
$out['length'] = $handle & 0x7f;
$length = &$out['length'];
if ($out['rsv1'] !== 0x0 || $out['rsv2'] !== 0x0 || $out['rsv3'] !== 0x0) {
return [
'opcode' => $out['opcode'],'error' => 'protocol error (1002)'
];
}
if ($length === 0) {
$out['payload'] = '';
return $out;
}
if ($length === 0x7e) {
$handle = unpack('nl',fread($socket,2));
$length = $handle['l'];
} elseif ($length === 0x7f) {
$handle = unpack('N*l',8));
$length = isset($handle['l2']) ? $handle['l2'] : $length;
if ($length > 0x7fffffffffffffff) {
return [
'opcode' => $out['opcode'],'error' => 'content length mismatch'
];
}
}
if ($out['mask'] === 0x0) {
$msg = '';
$readLength = 0;
while ($readLength < $length) {
$toRead = $length - $readLength;
$msg .= fread($socket,$toRead);
if ($readLength === strlen($msg)) {
break;
}
$readLength = strlen($msg);
}
$out['payload'] = $msg;
return $out;
}
$maskN = array_map('ord',str_split(fread($socket,4)));
$maskC = 0;
$bufferLength = 1024;
$message = '';
for ($i = 0; $i < $length; $i += $bufferLength) {
$buffer = min($bufferLength,$length - $i);
$handle = fread($socket,$buffer);
for ($j = 0,$_length = strlen($handle); $j < $_length; ++$j) {
$handle[$j] = chr(ord($handle[$j]) ^ $maskN[$maskC]);
$maskC = ($maskC + 1) % 4;
}
$message .= $handle;
}
$out['payload'] = json_decode($message);
return $out;
}
这里是在tcp下工作的客户端。
/index.PHP
<!DOCTYPE html>
<html>
<head>
<Meta charset='UTF-8'/>
<style type="text/css">
<!--
.chat_wrapper {
width: 500px;
margin-right: auto;
margin-left: auto;
background: #CCCCCC;
border: 1px solid #999999;
padding: 10px;
font: 12px 'lucida grande',tahoma,verdana,arial,sans-serif;
}
.chat_wrapper .message_Box {
background: #FFFFFF;
height: 150px;
overflow: auto;
padding: 10px;
border: 1px solid #999999;
}
.chat_wrapper .panel input {
padding: 2px 2px 2px 5px;
}
.system_msg {
color: #BDBDBD;
font-style: italic;
}
.user_name {
font-weight: bold;
}
.user_message {
color: #88B6E0;
}
-->
</style>
</head>
<body>
<?PHP
$colours = array('007AFF','FF7000','15E25F','CFC700','CF1100','CF00BE','F00');
$user_colour = array_rand($colours);
?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
//create a new WebSocket object.
let wsUri = "wss://carbonPHP.com:8888/test.PHP";
let websocket = new WebSocket(wsUri);
websocket.onopen = function (ev) { // connection is open
$('#message_Box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
};
$('#send-btn').click(function () { //use clicks message send button
let mymessage = $('#message').val(),//get message text
myname = $('#name').val(); //get user name
if (myname === "") { //empty name?
alert("Enter your Name please!");
return;
}
if (mymessage === "") { //emtpy message?
alert("Enter Some message Please!");
return;
}
//prepare json data
let msg = {
message: mymessage,name: myname,color: '<?=$colours[$user_colour] ?>'
};
//convert and send data to server
websocket.send(JSON.stringify(msg));
});
//#### Message received from server?
websocket.onmessage = function (ev) {
let msg = JSON.parse(ev.data),//PHP sends Json data
type = msg.type,//message type
umsg = msg.message,//message text
uname = msg.name,//user name
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 class="chat_wrapper">
<div class="message_Box" id="message_Box"></div>
<div class="panel">
<input type="text" name="name" id="name" placeholder="Your Name" maxlength="10" style="width:20%"/>
<input type="text" name="message" id="message" placeholder="Message" maxlength="80" style="width:60%"/>
<button id="send-btn">Send</button>
</div>
</div>
</body>
</html>
有人知道为什么要在文件名上重复1或将其追加吗?或者只是如何解决此问题?预先感谢您的帮助!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)