首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >何时处理Socket.io通知?

问何时处理Socket.io通知?
EN

Stack Overflow用户
提问于 2018-09-25 21:02:26
回答 3查看 4.5K关注 0票数 10

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

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

我成功地进行了交谈:

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

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

/因此,后端仅是Socket.io服务器,它也处理数据库

效果很好。

但是,有些事件并不是实时的,但我仍然希望用Socket.io向给定的用户发送通知。

例如:如果一个帖子是喜欢的,那么发送一个noti给邮件所有者

我已经编写了PHP文件,以便在数据库中保存类似的内容,但是

我该如何做通知部分,安全?

我想出了三个点子:

  1. 该应用程序向我的PHP+MySQL后端发送一个web请求,它处理那里的数据,然后返回“成功”后,应用程序(SWIFT)向邮件所有者发送通知(通过Socket.io XCode pod)。
代码语言:javascript
复制
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. 相同,但在从PHP返回“成功”后,它本身( PHP文件)处理发出的Socket.IO通知以及(我认为这是不可能的,我还没有找到任何PHP->Socket.io插件.)

-

  1. 该应用程序不向我的web PHP+MySQL文件发送任何内容,而是将整个" like“进程发送给我的NodeJs,Socket.IO服务器,它在那里处理它,保存到数据库中,然后发出通知(就像实时聊天部分,但这将是很多工作,因为我已经用PHP文件编写了所有其他代码)。

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

因为如果我第一次这样做,后端NodeJs+Socket.io服务器将不会检查喜欢的进程是否成功(因为它是客户端的)。

因此,任何人都有可能发送虚假的“类似”通知,比如10亿次。

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

EN

回答 3

Stack Overflow用户

发布于 2018-09-28 19:24:05

更简单的是.

忘记PHP,进入完整的Nodejs:

Express (您还可以将其与车把、& i18n结合使用)

使用express,您可以为传入请求构建一个路由器(GET、PUT、POST、.) 这意味着您可以使用它来呈现具有服务器端动态数据的页面。

代码语言:javascript
复制
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文件如下所示:

代码语言:javascript
复制
<!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是一个内存中的数据结构存储,可以用作数据库、缓存和消息代理。

PHPRedis @Github

使用PHP和Node.JS的Redis PubSub

在Redis上读取Node.js会话的一个快速示例

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

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

票数 7
EN

Stack Overflow用户

发布于 2018-10-04 08:10:08

我理解您的担忧,因为与其他框架/语言相比,整个项目的PHP代码更集中。为了纠正您的问题,下面是PHPV5.3和更高版本的Socket.io实现。

在此帮助下,您可以在PHP代码中使用socket.io库。下面您可以看到一个在PHP中使用Socket.io库的示例。

代码语言:javascript
复制
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();
票数 3
EN

Stack Overflow用户

发布于 2018-10-03 17:58:10

您可以创建多个web套接字通道。在您的例子中,您使用socket.io在NodeJS中添加了一个。您可以通过php方式添加另一个通道。

您可以以从NodeJS收听该频道的方式收听该频道。

很少有方便的链接1. http://php.net/manual/en/book.sockets.php 2. 如何在PHP中创建websockets服务器

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52506653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档