[英]Integrating Socket.io with a PHP web app and Nginx
我目前正在開發一個包含聊天功能的移動應用。 API后端是使用Laravel構建的,但是在聊天中,我們將使用Socket.io。 我們正在使用“讓我們加密”中的SSL證書
我在使Socket.io工作時遇到麻煩。 它似乎確實在連接,因為在頁面加載時,“新連接”消息似乎顯示在瀏覽器的控制台中,但是似乎沒有收到我發送的任何消息。 我認為Nginx配置可能不正確。
這是當前最小形式的聊天腳本:
var io = require('socket.io')(9000);
io.on('connection', function (socket) {
io.emit('connected', {'msg': 'Someone has connected'});
socket.on('messsage', function (data) {
io.emit('relaymessage', data);
});
socket.on('disconnect', function () {
io.emit('disconnected');
});
});
和客戶端實現:
<!DOCTYPE html>
<html>
<head>
<title>Laravel</title>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
<style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Chat</div>
<div id="output"></div>
<form>
<textarea id="message"></textarea>
<button id="submit">Submit</button>
</form>
</div>
</div>
<script type="text/javascript" src="//code.jquery.com/jquery-2.2.3.min.js"></script>>
<script type="text/javascript" src="/client.js"></script>>
<script type="text/javascript">
var socket = io(window.location.href);
var txt = document.getElementById('message');
var btn = document.getElementById('submit');
socket.on('connected', function (data) {
console.log('New connection');
});
socket.on('relaymessage', function (data) {
console.log(data);
$('div#output').append('<p>' + data.content + '</p>');
});
socket.on('disconnected', function () {
console.log('Disconnected');
});
$('button#submit').on('click', function (event) {
event.preventDefault();
var content = $('textarea#message').val();
socket.emit('message', { content: content });
$('textarea#message').val('');
});
</script>>
</body>
</html>
這是我的Nginx配置:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com.com/privkey.pem;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
client_max_body_size 50M;
server_tokens off;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
root /var/www/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip on;
gzip_proxied any;
gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml-rss text/javascript text/js application/json;
expires 1y;
charset utf-8;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location /socket.io/ {
proxy_pass http://localhost:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
location ~ /.well-known {
root /var/www/public;
allow all;
}
}
關於發生了什么問題有任何想法嗎?
最終解決了。 第一個問題是QUEUE_DRIVER
和BROADCAST_DRIVER
都設置為redis
,這破壞了廣播系統-它使用PUSH
代替PUBLISH
。 因此,我刪除了QUEUE_DRIVER
並正確接收了消息。
使用HTTPS並加載SSL證書所需的聊天腳本:
var fs = require('fs');
var pkey = fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem');
var pcert = fs.readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem')
var options = {
key: pkey,
cert: pcert
};
var app = require('https').createServer(options);
var io = require('socket.io')(app);
var Redis = require('ioredis');
var redis = new Redis();
app.listen(9000, function() {
console.log('Server is running!');
});
function handler(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.writeHead(200);
res.end('');
}
io.on('connection', function(socket) {
//
});
redis.psubscribe('*', function(err, count) {
//
});
redis.on('pmessage', function(subscribed, channel, message) {
message = JSON.parse(message);
console.log('Channel is ' + channel + ' and message is ' + message);
io.emit(channel, message.data);
});
客戶端實現需要使用secure
參數:
var url = window.location.protocol + '//' + window.location.hostname;
var socket = io(url, {
'secure': true,
'reconnect': true,
'reconnection delay': 500,
'max reconnection attempts': 10
});
var chosenEvent = 'room_' + room.id;
socket.on(chosenEvent, function (data) {
console.log(data);
});
一旦進行了這些更改,它就可以正常工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.