php - 何时处理 Socket.io 通知?

标签 php node.js swift sockets notifications

我正在开发一个用 SWIFT 编写的 IOS 社交应用程序。

后端是 PHP, MySQL(用于事件处理),+一点 NodeJS, Socket.io(用于实时聊天和通知)


我已成功聊天:

当用户发送消息时,Socket.io 服务器会通过以下方式处理它:

  • 将数据插入数据库
  • 如果成功则向所有参与用户发送消息

/所以后端只是 Socket.io 服务器,它也处理数据库


工作正常。

但是有些事件并不意味着是实时的,但我仍然想使用 Socket.io 向给定用户发送通知

for example: if a post has been liked, then send a noti to the posts owner

我已经编写了PHP文件用于在数据库中保存类似的东西,但是

通知部分应该怎么做,安全吗?


我想出了 3 个想法:

  1. The app sends a web request to my PHP+MySQL backend, it handles the data there, then after returning back "success", the application (SWIFT) sends a notification to the post owner (via Socket.io XCode pod)
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()
    }
  1. same, but after returning back "success" from the PHP, itself (the PHP file) handles the Socket.IO notification emitting as well (I think this is not possible, I haven't found any PHP->Socket.io plugins..)

-

  1. The app does not send anything to my web PHP+MySQL file, instead it sends the whole "like" process to my NodeJs, Socket.IO server, it handles it there, saves it to the database, then emits the notifications (Just like the real time chat part, but this would be a lot work because I have already written all the other code in PHP files)

第一种情况对我来说是最理想的,但我害怕它会被破解..

因为如果我用第一种方式,后端NodeJs+Socket.io服务器不会检查点赞过程是否成功(因为它是在客户端检查的)

所以很可能任何人都可以发送虚假的“点赞”通知,比如十亿次。


那么也许第二个选项也很好,这样后端就可以同时处理检查和通知发送,但遗憾的是没有用于 PHP 的 Socket.io 插件

最佳答案

这样会更简单...

忘记 PHP,使用完整的 Nodejs:

Express(您也可以将它与 handlebarsi18n 结合使用以实现多语言目的)

With express you can build a router for incoming requests (GET,PUT,POST,...)

This means that you can use it to render pages with server-side dynamic data

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(如果你想运行超过 1 个服务器实例,没问题,查找 socket.io-redis)

您可以通过不同的方式将 express 与 socket.io 结合起来,您甚至可以为您的套接字协议(protocol)使用基于 cookie 的身份验证。因此,当一个事件发生时,您实际上可以 100% 判断它是否是合法用户及其用户 ID。


为了防止喜欢的垃圾邮件...您必须以某种方式控制它们。 您应该存储 like 的操作,因此不能对同一个帖子重复多次(因此 user-id 和 post-id 似乎是这里的重要变量)



更新来了:

既然你很清楚你想要一个 php 和 nodejs 组合:

Redis is an in-memory data structure store which can be used as a database, a cache and a message broker.

PHPRedis @Github

Redis PubSub with PHP and Node.JS

A quick example of Node.js reading PHP session on Redis

使用 Redis,您可以轻松地从您的 nodejs 实例中监听 php 事件。

我建议您也考虑一下您系统的 future 扩展,并尝试学习更多 nodejs 以便能够从 php 继续前进。

关于php - 何时处理 Socket.io 通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52506653/

相关文章:

php - 在循环中插入数据并仅回显一次

php - 如何使用 PHP 将大文本插入数据库?

javascript - 如何在客户端 javascript 中访问 Passport 的 req.user 变量?

javascript - 尝试理解 Promise()

ios - 以编程方式创建 UITabBarController,仅显示一个选项卡

ios - Metal 同时有纹理和无纹理,多重混合

ios - 如何获取textview中动态变化的Text的内容高度?

php - 不能 json_encode() 数组或 Laravel 集合 : "Type is not supported"

node.js - Socket.io 和现代浏览器不工作

php - 在 php 中检测 mysql 支持