我正在开发一个用SWIFT编写的IOS社交应用程序。
后端是PHP, MySQL (用于事件处理),+一点NodeJS, Socket.io (用于实时聊天和通知)。
我成功地进行了交谈:
当用户发送消息时,Socket.io服务器以下列方式处理它:
/因此,后端仅是Socket.io服务器,它也处理数据库
效果很好。
但是,有些事件并不是实时的,但我仍然希望用Socket.io向给定的用户发送通知。
例如:如果一个帖子是喜欢的,那么发送一个noti给邮件所有者
我已经编写了PHP文件,以便在数据库中保存类似的内容,但是
我该如何做通知部分,安全?
我想出了三个点子:
func likePost(postId : Int, completion: @escaping (ActionResult?)->()){
let connectUrl = URL(string: appSettings.url + "/src/main/like.php")
var request = URLRequest(url: connectUrl!)
request.httpMethod = "POST"
let postString = "userId=\(userId)&session=\(session)&pId=\(postId)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
return completion(ActionResult(type: 0, code: 0, title: "error", message: "something went wrong"))
}
do {
let responseJson = try JSONSerialization.jsonObject(with: data!, options: [])
if let responseArray = responseJson as? [String: Any] {
let responseStatus = responseArray["status"] as? String
let responseTitle = responseArray["title"] as? String
let responseMessage = responseArray["message"] as? String
if responseStatus != "1" {
return completion(ActionResult(type: 0, code: 0, title: "error", message: "something went wrong"))
}
// SUCCESS, SEND NOTI WITH SOCKET.IO
socket.emit("notification_likedPost", ["postId": postId)
return completion(ActionResult(type: 1, title: "success", message: "yay"))
}
} catch {
return completion(ActionResult(type: 0, code: 0, title: "error", message: "something went wrong"))
}
}
task.resume()
}-
--第一种情况对我来说是最理想的,但我害怕它会被破解。
因为如果我第一次这样做,后端NodeJs+Socket.io服务器将不会检查喜欢的进程是否成功(因为它是客户端的)。
因此,任何人都有可能发送虚假的“类似”通知,比如10亿次。
然后也许第二个选项也会很好,这样后端就可以同时处理检查和通知发送,,但是遗憾的是,没有Socket.io 插件。
发布于 2018-09-28 19:24:05
更简单的是.
忘记PHP,进入完整的Nodejs:
Express (您还可以将其与车把、& i18n结合使用)
使用express,您可以为传入请求构建一个路由器(
GET、PUT、POST、.) 这意味着您可以使用它来呈现具有服务器端动态数据的页面。
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
// Register Handlebars view engine
app.engine('handlebars', exphbs());
// Use Handlebars view engine
app.set('view engine', 'handlebars');
var visit_counter = 0;
app.get('/', (req, res) => {
var time_stamp = Date.now(); visit_counter++
res.render('index',{"timestamp":time_stamp,"visits":visit_counter});
});
app.listen(3000, () => {
console.log('Example app is running → PORT 3000');
});views/index.hbs文件如下所示:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example App</title>
</head>
<body>
<p> Current Time : {{timestamp}} </p>
<p> Total Visits : {{visits}} </p>
</body>
</html>以上部分是在最终html中呈现服务器端数据的示例。
socket.io-redis) (如果要运行服务器的多个实例,没有问题,请查找Socket.io )。
您可以以不同的方式与socket.io结合,甚至可以为套接字协议使用基于cookie的身份验证。所以当一个事件出现的时候,你可以百分之百的告诉它的合法用户和它的用户id。
防止垃圾邮件的喜欢..。你必须控制他们。您应该存储类似的操作,因此不能对同一个帖子重复多次(因此,user和post似乎是这里的重要变量)。
下面是更新:
由于您非常清楚地表示您需要一个php & nodejs组合体:
Redis是一个内存中的数据结构存储,可以用作数据库、缓存和消息代理。
使用Redis,您可以轻松地侦听nodejs实例中的php事件。
我建议您也考虑一下系统的未来扩展,并尝试学习更多的nodejs,以便能够从php中继续前进。
发布于 2018-10-04 08:10:08
我理解您的担忧,因为与其他框架/语言相比,整个项目的PHP代码更集中。为了纠正您的问题,下面是PHPV5.3和更高版本的Socket.io实现。
在此帮助下,您可以在PHP代码中使用socket.io库。下面您可以看到一个在PHP中使用Socket.io库的示例。
use Workerman\Worker;
use PHPSocketIO\SocketIO;
// listen port 2020 for socket.io client
$io = new SocketIO(2020);
$io->on('connection', function($socket){
$socket->addedUser = false;
// when the client emits 'new message', this listens and executes
$socket->on('new message', function ($data)use($socket){
// we tell the client to execute 'new message'
$socket->broadcast->emit('new message', array(
'username'=> $socket->username,
'message'=> $data
));
});
// when the client emits 'add user', this listens and executes
$socket->on('add user', function ($username) use($socket){
global $usernames, $numUsers;
// we store the username in the socket session for this client
$socket->username = $username;
// add the client's username to the global list
$usernames[$username] = $username;
++$numUsers;
$socket->addedUser = true;
$socket->emit('login', array(
'numUsers' => $numUsers
));
// echo globally (all clients) that a person has connected
$socket->broadcast->emit('user joined', array(
'username' => $socket->username,
'numUsers' => $numUsers
));
});
// when the client emits 'typing', we broadcast it to others
$socket->on('typing', function () use($socket) {
$socket->broadcast->emit('typing', array(
'username' => $socket->username
));
});
// when the client emits 'stop typing', we broadcast it to others
$socket->on('stop typing', function () use($socket) {
$socket->broadcast->emit('stop typing', array(
'username' => $socket->username
));
});
// when the user disconnects.. perform this
$socket->on('disconnect', function () use($socket) {
global $usernames, $numUsers;
// remove the username from global usernames list
if($socket->addedUser) {
unset($usernames[$socket->username]);
--$numUsers;
// echo globally that this client has left
$socket->broadcast->emit('user left', array(
'username' => $socket->username,
'numUsers' => $numUsers
));
}
});
});
Worker::runAll();发布于 2018-10-03 17:58:10
您可以创建多个web套接字通道。在您的例子中,您使用socket.io在NodeJS中添加了一个。您可以通过php方式添加另一个通道。
您可以以从NodeJS收听该频道的方式收听该频道。
很少有方便的链接1. http://php.net/manual/en/book.sockets.php 2. 如何在PHP中创建websockets服务器
https://stackoverflow.com/questions/52506653
复制相似问题