wss सेवा बनाना
प्रश्न:
Workerman कैसे एक wss सेवा बनाए, ताकि क्लाइंट wss प्रोटोकॉल के माध्यम से संपर्क कर सकें, जैसे कि WeChat लघु कार्यक्रम में सर्वर से कनेक्ट करना।
उत्तर:
wss प्रोटोकॉल दरअसल websocket+SSL है, अर्थात यह websocket प्रोटोकॉल पर एक SSL लेयर जोड़ता है, जो कि https (http+SSL) के समान है।
इसलिए केवल websocket प्रोटोकॉल के आधार पर SSL को सक्षम करना होगा ताकि wss प्रोटोकॉल का समर्थन किया जा सके।
विधि एक, nginx/apache के माध्यम से SSL प्रॉक्सी करना (सिफारिश की जाती है)
सिफारिश के कारण
- 443 पोर्ट को पुन: उपयोग करते हुए, क्लाइंट को कनेक्शन के दौरान पोर्ट निर्दिष्ट करने की आवश्यकता नहीं होती
- SSL प्रमाणपत्र का केंद्रीकृत प्रबंधन, वेबसाइट कॉन्फ़िगरेशन का पुन: उपयोग कर सकते हैं
- लोड बैलेंस कर सकते हैं
- अंतर्निहित लॉग निगरानी
- बेहतर संगतता
संपर्क सिद्धांत और प्रक्रिया
-
क्लाइंट wss कनेक्शन के लिए nginx/apache में अनुरोध भेजता है
-
nginx/apache wss प्रोटोकॉल डेटा को ws प्रोटोकॉल डेटा में बदलता है और इसे Workerman के websocket प्रोटोकॉल पोर्ट पर अग्रेषित करता है
-
Workerman डेटा प्राप्त करता है और व्यावसायिक लॉजिक के साथ प्रक्रिया करता है
-
जब Workerman क्लाइंट को मेसेज भेजता है, तो यह विपरीत प्रक्रिया होती है, डेटा nginx/apache के माध्यम से wss प्रोटोकॉल में परिवर्तित होता है और फिर क्लाइंट को भेजा जाता है
nginx कॉन्फ़िगरेशन संदर्भ
पूर्ववर्ती और तैयारी:
-
nginx पहले से स्थापित है, संस्करण 1.3 या उससे ऊपर होना चाहिए
-
मान लीजिए Workerman 8282 पोर्ट (websocket प्रोटोकॉल) पर सुनता है
-
प्रमाणपत्र (pem/crt फ़ाइल और key फ़ाइल) पहले से ही प्राप्त किया है, मान लें कि यह /etc/nginx/conf.d/ssl में रखा गया है
-
nginx का उपयोग करके 443 पोर्ट को wss प्रॉक्सी सेवा प्रदान करने के लिए उपयोग करने की योजना है (पोर्ट की आवश्यकता के अनुसार बदली जा सकती है)
-
nginx आमतौर पर अन्य सेवाओं को चलाने वाली वेबसाइट सर्वर के रूप में कार्य करता है, इसलिए मौजूदा साइट का उपयोग प्रभावित न हो इसके लिए यहाँ एक पता
डोमेन.com/wssको wss प्रॉक्सी एंट्री के रूप में उपयोग किया जाता है। अर्थात क्लाइंट कनेक्शन का पता wss://डोमेन.com/wss होगा
nginx कॉन्फ़िगरेशन निम्नलिखित जैसा होगा:
server {
listen 443;
# डोमेन कॉन्फ़िगरेशन छोड़ दिया गया है...
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;
}
# location / {} साइट का अन्य कॉन्फ़िगरेशन...
}
परीक्षण
// प्रमाणपत्र डोमेन की जांच करेगा, कृपया डोमेन से कनेक्ट करें। ध्यान दें कि यहाँ पोर्ट नहीं लिखा गया है
ws = new WebSocket("wss://डोमेन.com/wss");
ws.onopen = function() {
alert("कनेक्शन सफल");
ws.send('tom');
alert("सर्वर को एक स्ट्रिंग भेजी गई: tom");
};
ws.onmessage = function(e) {
alert("सर्वर से संदेश प्राप्त हुआ: " + e.data);
};
Apache का उपयोग करके wss प्रॉक्सी करना
आप Apache का उपयोग करके wss को Workerman के लिए अग्रेषित करने के लिए भी कर सकते हैं।
तैयारी का कार्य:
-
GatewayWorker 8282 पोर्ट (websocket प्रोटोकॉल) पर सुनता है
-
SSL प्रमाणपत्र पहले से प्राप्त किया गया है, मान लें कि यह /server/httpd/cert/ में रखा गया है
-
Apache 443 पोर्ट को निर्दिष्ट पोर्ट 8282 पर अग्रेषित कर रहा है
-
httpd-ssl.conf पहले से लोड किया गया है
-
OpenSSL स्थापित है
proxy_wstunnel_module मॉड्यूल सक्षम करें
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
SSL और प्रॉक्सी कॉन्फ़िगरेशन
#extra/httpd-ssl.conf
DocumentRoot "/वेबसाइट/डायरेक्टरी"
ServerName डोमेन
# प्रॉक्सी कॉन्फ़िगरेशन
SSLProxyEngine on
ProxyRequests Off
ProxyPass /wss ws://127.0.0.1:8282/wss
ProxyPassReverse /wss ws://127.0.0.1:8282/wss
# SSL प्रोटोकॉल समर्थन को जोड़ें, असुरक्षित प्रोटोकॉल हटा दें
SSLProtocol all -SSLv2 -SSLv3
# एन्क्रिप्शन सेट को निम्नलिखित के रूप में संशोधित करें
SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM
SSLHonorCipherOrder on
# प्रमाणपत्र सार्वजनिक कुंजी कॉन्फ़िगरेशन
SSLCertificateFile /server/httpd/cert/your.pem
# प्रमाणपत्र निजी कुंजी कॉन्फ़िगरेशन
SSLCertificateKeyFile /server/httpd/cert/your.key
# प्रमाणपत्र श्रृंखला कॉन्फ़िगरेशन
SSLCertificateChainFile /server/httpd/cert/chain.pem
परीक्षण
// प्रमाणपत्र डोमेन की जांच करेगा, कृपया डोमेन से कनेक्ट करें। ध्यान दें कि यहाँ कोई पोर्ट नहीं है
ws = new WebSocket("wss://डोमेन.com/wss");
ws.onopen = function() {
alert("कनेक्शन सफल");
ws.send('tom');
alert("सर्वर को एक स्ट्रिंग भेजी गई: tom");
};
ws.onmessage = function(e) {
alert("सर्वर से संदेश प्राप्त हुआ: " + e.data);
};
विधि दो, सीधे Workerman पर SSL सक्षम करना (सिफारिश नहीं की जाती)
ध्यान दें
nginx/apache SSL प्रॉक्सी के माध्यम से और Workerman SSL सेटिंग में से एक को चुनें, दोनों को एक साथ सक्षम नहीं किया जा सकता।
तैयारी का कार्य:
-
Workerman संस्करण >= 3.3.7
-
PHP में openssl एक्सटेंशन स्थापित है
-
प्रमाणपत्र (pem/crt फ़ाइल और key फ़ाइल) पहले से प्राप्त किया गया है जिसे किसी भी डिस्क डायरेक्टरी में रखा गया है
कोड:
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// प्रमाणपत्र बेहतर तरीके से प्राप्त किया गया प्रमाणपत्र होना चाहिए
$context = array(
// अधिक ssl विकल्पों के लिए कृपया मैनुअल देखें http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// कृपया पूर्ण पथ का उपयोग करें
'local_cert' => 'डिस्क पथ/server.pem', // यह crt फ़ाइल भी हो सकता है
'local_pk' => 'डिस्क पथ/server.key',
'verify_peer' => false,
'allow_self_signed' => true, // यदि यह एक स्व-हस्ताक्षरित प्रमाणपत्र है तो इस विकल्प को सक्षम करें
)
);
// यहाँ websocket प्रोटोकॉल सेट किया गया है (पोर्ट कोई भी हो, लेकिन यह सुनिश्चित करना होगा कि यह अन्य प्रोग्रामों द्वारा कब्जा नहीं किया गया हो)
$worker = new Worker('websocket://0.0.0.0:8282', $context);
// transport के SSL को सक्षम करें, websocket+ssl यानी wss
$worker->transport = 'ssl';
$worker->onMessage = function(TcpConnection $con, $msg) {
$con->send('ok');
};
Worker::runAll();
ऊपर दिए गए कोड के माध्यम से, Workerman wss प्रोटोकॉल सुनता है, क्लाइंट wss प्रोटोकॉल के माध्यम से Workerman से सुरक्षित तात्कालिक संचार करने के लिए कनेक्ट कर सकता है।
परीक्षण
Chrome ब्राउज़र खोलें, F12 दबाकर डिबग कंसोल खोलें, Console सेक्शन में (या नीचे दिए गए कोड को HTML पृष्ठ में JS के माध्यम से चलाएं)
// प्रमाणपत्र डोमेन की जांच करेगा, कृपया डोमेन से कनेक्ट करें, ध्यान दें कि यहाँ पोर्ट नंबर है
ws = new WebSocket("wss://डोमेन.com:8282");
ws.onopen = function() {
alert("कनेक्शन सफल");
ws.send('tom');
alert("सर्वर को एक स्ट्रिंग भेजी गई: tom");
};
ws.onmessage = function(e) {
alert("सर्वर से संदेश प्राप्त हुआ: " + e.data);
};
सामान्य त्रुटियाँ
SSL routines:SSL23_GET_CLIENT_HELLO:http request
सूचना है कि क्लाइंट ws://डोमेन.com का उपयोग करके पहुँचता है जो कारण है, सही पहुँच पता wss://डोमेन.com होना चाहिए, जिसका अर्थ है wss से शुरू करना।
इस समस्या का प्रकट होना अधिकांश परिदृश्यों में तब होता है जब पोर्ट मूलतः ws के लिए था, अचानक wss में बदल दिया गया, तब कुछ क्लाइंट पृष्ठ नहीं ताज़ा हुए, अभी भी ws के तरीके से पहुँचने का प्रयास कर रहे हैं, जिससे त्रुटि होती है।
इस त्रुटि को अनदेखा किया जा सकता है, यह सामान्य wss कनेक्शन को प्रभावित नहीं करता है।
ध्यान दें:
-
यदि 443 पोर्ट का उपयोग करना अनिवार्य है तो कृपया उपरोक्त पहले समाधान nginx/apache प्रॉक्सी विधि का उपयोग करके wss प्राप्त करें।
-
wss पोर्ट केवल wss प्रोटोकॉल के माध्यम से पहुँच योग्य है, ws wss पोर्ट तक पहुँच नहीं सकता।
-
प्रमाणपत्र आमतौर पर डोमेन से बंधे होते हैं, इसलिए परीक्षण करते समय क्लाइंट कृपया डोमेन से कनेक्ट करें, IP का उपयोग न करें।
-
यदि पहुँच में कोई समस्या आती है, तो कृपया सर्वर फ़ायरवॉल की जाँच करें।
-
इस विधि के लिए PHP संस्करण >= 5.6 आवश्यक है, क्योंकि WeChat लघु कार्यक्रम tls1.2 की आवश्यकता होती है, जबकि PHP 5.6 से नीचे के संस्करण tls1.2 का समर्थन नहीं करते हैं।
संबंधित लेख:
प्रॉक्सी के माध्यम से क्लाइंट का असली IP प्राप्त करें
workerman का ssl संदर्भ विकल्प