Créer un service wss
Question :
Comment créer un service wss avec Workerman, de sorte que les clients puissent se connecter en utilisant le protocole wss, par exemple pour se connecter depuis une mini-application WeChat?
Réponse:
Le protocole wss est en réalité websocket + SSL, c'est-à-dire qu'il ajoute une couche SSL au protocole websocket, similaire à https (http + SSL). Par conséquent, il suffit d'activer SSL sur le protocole websocket pour prendre en charge le protocole wss.
Méthode 1 : Utilisation de Nginx/Apache pour la représentation SSL (recommandé)
Principe et processus de communication :
- Le client établit une connexion wss vers Nginx/Apache.
- Nginx/Apache convertit les données du protocole wss en données du protocole ws et les transmet au port du protocole WebSocket de Workerman.
- Workerman reçoit les données et effectue le traitement logique.
- Lorsque Workerman envoie un message au client, le processus est inversé : les données sont converties en protocole wss par Nginx/Apache, puis envoyées au client.
Configuration Nginx
Prérequis et préparation :
- Nginx est installé, version supérieure ou égale à 1.3.
- Supposons que Workerman écoute sur le port 8282 (protocole websocket).
- Un certificat (fichier pem/crt et fichier clé) a été demandé et est stocké dans /etc/nginx/conf.d/ssl.
- Vous prévoyez d'utiliser Nginx pour activer le port 443 en tant que service proxy wss (le port peut être modifié selon vos besoins).
- Habituellement, Nginx sert à d'autres services web. Pour ne pas interférer avec les sites existants, nous utilisons l'adresse "domain.com/wss" comme point d'entrée de proxy wss. Ainsi, l'adresse de connexion du client sera wss://domain.com/wss.
Exemple de configuration Nginx :
server {
listen 443;
# Configuration de domaine omise...
ssl on;
ssl_certificate /etc/ssl/server.pem;
ssl_certificate_key /etc/ssl/server.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_protocols SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
location /wss
{
proxy_pass http://127.0.0.1:8282;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
# Emplacement / {} Autres configurations du site…
}
Test :
// Le certificat vérifie le domaine, veuillez utiliser le nom de domaine pour la connexion. Notez qu'aucun port n'est spécifié ici.
ws = new WebSocket("wss://domain.com/wss");
ws.onopen = function() {
alert("Connexion établie");
ws.send('tom');
alert("Envoi d'une chaîne au serveur : tom");
};
ws.onmessage = function(e) {
alert("Message reçu du serveur : " + e.data);
};
Utilisation d'Apache pour la représentation wss
Il est également possible d'utiliser Apache comme proxy wss pour transférer vers Workerman.
Prérequis :
- GatewayWorker écoute sur le port 8282 (protocole websocket).
- Un certificat SSL a été demandé et est stocké dans /server/httpd/cert/.
- Apache est configuré pour transférer le port 443 vers le port 8282 spécifié.
- httpd-ssl.conf est chargé.
- OpenSSL est installé.
Activation du module proxy_wstunnel_module :
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
Configuration SSL et proxy :
# extra/httpd-ssl.conf
DocumentRoot "/chemin/vers/le/site"
ServerName domaine
# Configuration du proxy
SSLProxyEngine on
ProxyRequests Off
ProxyPass /wss ws://127.0.0.1:8282/wss
ProxyPassReverse /wss ws://127.0.0.1:8282/wss
# Ajout de la prise en charge de protocole SSL, suppression des protocoles non sécurisés
SSLProtocol all -SSLv2 -SSLv3
# Modification des suites de chiffrement comme suit
SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM
SSLHonorCipherOrder on
# Configuration de la clé publique du certificat
SSLCertificateFile /server/httpd/cert/votre.pem
# Configuration de la clé privée du certificat
SSLCertificateKeyFile /server/httpd/cert/votre.key
# Configuration du chaînage de certificats
SSLCertificateChainFile /server/httpd/cert/chain.pem
Test :
// Le certificat vérifie le domaine, veuillez utiliser le nom de domaine pour la connexion. Notez qu'aucun port n'est spécifié ici.
ws = new WebSocket("wss://domain.com/wss");
ws.onopen = function() {
alert("Connexion établie");
ws.send('tom');
alert("Envoi d'une chaîne au serveur : tom");
};
ws.onmessage = function(e) {
alert("Message reçu du serveur : " + e.data);
};
Méthode 2 : Activation directe de SSL avec Workerman (non recommandé)
Remarque :
L'utilisation de Nginx/Apache pour la représentation SSL et la configuration SSL avec Workerman sont mutuellement exclusives.
Prérequis :
- Version Workerman >= 3.3.7.
- PHP est installé avec l'extension openssl.
- Un certificat (fichier pem/crt et clé) est stocké dans un répertoire de votre choix.
Code :
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// Un certificat valide est recommandé
$context = array(
// Plus d'options SSL sont disponibles dans la documentation http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// Utilisez des chemins absolus
'local_cert' => 'chemin/vers/server.pem', // Ou un fichier crt
'local_pk' => 'chemin/vers/server.key',
'verify_peer' => false,
'allow_self_signed' => true, // Nécessaire pour les certificats autosignés
)
);
// Ici, le protocole est websocket (le port est arbitraire, mais doit être disponible et non utilisé par d'autres programmes)
$worker = new Worker('websocket://0.0.0.0:8282', $context);
// Configurer le transport pour activer SSL, websocket+SSL signifie wss
$worker->transport = 'ssl';
$worker->onMessage = function(TcpConnection $con, $msg) {
$con->send('ok');
};
Worker::runAll();
Avec ce code, Workerman écoute le protocole wss et les clients peuvent se connecter en utilisant le protocole wss pour établir une communication sécurisée en temps réel avec Workerman.
Test :
Ouvrez Google Chrome, appuyez sur F12 pour ouvrir la console de débogage, puis saisissez (ou intégrez le code ci-dessous dans une page HTML pour l'exécuter via JavaScript) :
// Le certificat vérifie le domaine et doit être utilisé pour la connexion, notez la présence du port ici
ws = new WebSocket("wss://domain.com:8282");
ws.onopen = function() {
alert("Connexion établie");
ws.send('tom');
alert("Envoi d'une chaîne au serveur : tom");
};
ws.onmessage = function(e) {
alert("Message reçu du serveur : " + e.data);
};
Remarques :
- Si vous devez utiliser le port 443, veuillez utiliser la première méthode de représentation SSL avec Nginx/Apache pour implémenter wss.
- Le port wss ne peut être accessible que via le protocole wss, le protocole ws ne peut pas accéder au port wss.
- Les certificats sont généralement liés à des noms de domaine, donc pour les tests, veuillez utiliser un nom de domaine pour la connexion et n'utilisez pas l'adresse IP.
- Si vous rencontrez des problèmes d'accès, veuillez vérifier le pare-feu du serveur.
- Cette méthode nécessite une version PHP >= 5.6, car les mini-applications WeChat requièrent TLS 1.2, et PHP versions antérieures à 5.6 ne prennent pas en charge TLS 1.2.
Articles connexes :
Récupération de l'adresse IP réelle du client à travers le proxy
Référence des options de contexte SSL pour Workerman