我是网络开发的初学者。最近我一直在完全基于PHP和JS/jQuery(我没有使用任何框架)的实时聊天网站。目前,我的设置只是简单的AJAX轮询,显然不如我希望的那样好。我的数据库是一个MYSQL数据库。实时聊天,消息处理 - Socket.io,PHP,MySQL,Apache
我看过的WebSockets和我的新开始的计划是创建一个Socket.io服务器的NodeJS将处理消息(How to integrate nodeJS + Socket.IO and PHP?),我想过在一个MySQL数据库(MySQL with Node.js)存储这些信息。
这是我目前的(不多,我想澄清如何进步之前,我实际上取得进展)。这是我的测试设置,实际聊天中使用的HTML显然有点不同。
的Node.js服务器:
// NODE
var socket = require('socket.io');
var express = require('express');
var https = require('https');
var http = require('http'); //Old
var fs = require('fs');
var app = express();
//Working HTTPS server
var server = https.createServer({
key: fs.readFileSync('/etc/letsencrypt/live/%site%/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/%site%/fullchain.pem')
},app);
// var server = https.createServer(app); Won't work cause no cert.
var io = socket.listen(server);
console.log("Server Started");
io.sockets.on('connection', function(client) {
console.log("New client !");
client.on('message', function(data) {
console.log('Message received ' + data); //Logs recieved data
io.sockets.emit('message', data); //Emits recieved data to client.
});
});
server.listen(8080, function() {
console.log('Listening');
});
JS客户端脚本:
var socket = io.connect('https://%site%:8080');
document.getElementById("sbmt").onclick = function() {
socket.emit('message', "My Name is: " + document.getElementById('nameInput').value + " i say: " + document.getElementById('messageInput').value);
};
socket.on('message', function(data) {
alert(data);
});
我的超简单的测试HTML:
<form id="messageForm">
<input type="text" id="nameInput"></input>
<input type="text" id="messageInput"></input>
<button type="button" id="sbmt">Submits</button>
</form>
PHP需要说明一下 - 目前当有人连接到我的网站我运行session_start()
。这是因为我想要有类似匿名会话的内容。我通过$_SESSION
变量来区分登录和匿名用户。 anon用户将$_SESSION['anon']
设置为true,并且不会设置$_SESSION['username']
。登录用户显然会倒过来。
谈到聊天时 - 既可以登录用户,也可以匿名用户使用。当用户是匿名用户时,会从数据库或随机名称生成随机用户名。当用户登录时,他自己的用户名被选中。现在我用Ajax查询系统的工作原理是这样的:
用户输入的消息(在当前的聊天解决方案,而不是测试HTML我上面发),并按下回车和AJAX调用到下面的函数取得:
function sendMessage($msg, $col) {
GLOBAL $db;
$un = "";
if (!isset($_SESSION['username'])) {
$un = self::generateRandomUsername();
} else {
$un = $_SESSION['username'];
}
try {
$stmt = $db->prepare('INSERT INTO chat (id, username, timestamp, message, color) VALUES (null, :un, NOW(), :msg, :col)');
$stmt->bindParam(':un', $un, PDO::PARAM_STR);
$stmt->bindValue(':msg', strip_tags(stripslashes($msg)), PDO::PARAM_STR); //Stripslashes cuz it saved \\\ to the DB before quotes, strip_tags to prevent malicious scripts. TODO: Whitelist some tags.
$stmt->bindParam(':col', $col, PDO::PARAM_STR);
} catch (Exception $e) {
var_dump($e->getMessage());
}
$stmt->execute();
}
(请不要讨厌我的坏代码和蹩脚的异常处理,这不是任何官方项目)。该功能将用户消息输入到数据库。
为了接收新消息,我使用了JS的setTimeout()
函数,在新消息之后每隔1秒运行一次AJAX检查。我保存显示在JS的最后一条消息的ID,并发送ID作为参数传递给这个PHP函数(和它的运行每1秒):
/* Recieve new messages, ran every 1s by Ajax call */
function recieveMessage($msgid) {
//msgid is latest msg id in this case
GLOBAL $db;
$stmt = $db->prepare('SELECT * FROM chat WHERE id > :id');
$stmt->bindParam(':id', $msgid, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
return json_encode($result);
}
的问题是:如何实现类似的东西,但与我前面提到的node.js服务器和websockets的设置?我需要以某种方式区分登录用户和匿名用户。我的第一个想法是只需从node.js服务器向PHP运行ajax调用并传递消息数据,PHP就会像现在一样将其插入到数据库中。但是这种情况下的问题是如何将消息再次发送给客户端?用户名是在消息被输入到数据库时应用的,这意味着我必须调用AJAX保存到数据库,然后调用另一个AJAX来提取新输入的消息并将其发送给客户端,或者创建一个函数插入并提取并返回提取的消息。但是,当两个消息完全同时输入时,这不会导致问题吗?
是否有可能在Node.js中访问PHP会话变量?然后,我可以重写所有的数据库查询在Node.js服务器而不是PHP中工作。
我再次道歉,如果我的代码或解释是凌乱。
请检查所有聊天相关应用程序的开源插件,如视频聊天,文本聊天等。[webRTC](https://webrtc.org/) – Webinion
@PandhiBhaumik这是一个非常有趣的插件,我一定会研究它。尽管如此,我仍想继续我开始的方式,至少对于这个项目来说。由于我是初学者,因此我从探索各种可能性中获得了大部分经验:) – Nae
如果您有机会了解答案,请将其作为答案发布。我也很困难在这里:(@Nae –