【问题标题】:Using deepstream.io for real-time voting使用 deepstream.io 进行实时投票
【发布时间】:2016-03-10 14:44:00
【问题描述】:

我使用deepstream.iorethinkdb 作为持久性存储,制作了一个实时投票系统的原型。到目前为止,它可以工作,并且多个浏览器可以保持同步以获取最新的投票计数(见下面的截图),但是,我不喜欢它的一件事是 vote count 在浏览器中递增,即发送到deepstream.io 远程服务器。

嵌入在客户端浏览器中的 JS 代码:

/**
        * Login to deepstream as Frank
        */
        var ds = deepstream( 'localhost:6020' ).login({ username: 'Frank'});
        var name = 'upvote';
        var upVotes;
        var voteText = $('.streaming-prices .vote');
        var record = ds.record.getRecord(name);
        $('#upvote_btn').click(function() {
            // on button click, increment the vote counts
            // set the record stored in the rethinkdb storage
            record.set({
                count: ++upVotes
            });
        });

        record.subscribe('count', function(newVal) {
            console.info('count updated, newVal: ', newVal);
            upVotes = newVal;
            voteText.text(newVal);
        });

server.js 代码:

var PermissionHandler = require( './permission-handler' );

var DeepstreamServer = require( 'deepstream.io' ),
    RdbC = require( 'deepstream.io-storage-rethinkdb' ),
    server = new DeepstreamServer();

server.set('host', '0.0.0.0');
server.set('port', 6020);
server.set( 'tcpHost', '0.0.0.0' );
server.set( 'tcpPort', '6022' );
server.set( 'permissionHandler', new PermissionHandler() );

server.set( 'storage', new RdbC({
    port: 28015,
    host: '127.0.0.1',
    splitChar: '/',
    database: 'votings',
    defaultTable: 'question'
}));

server.start();

所以你可以看到客户端的js代码直接增加了投票计数并更新了记录,这是要发送到deepstream.io服务器更新数据库的。 我不喜欢这部分,因为我不希望用户搞砸总票数相反,我希望客户端只是将+1 之类的内容发送到服务器,并让服务器更新持久性的总数。 我不确定这是否可能,有人可以摆脱一些光?我很感激

【问题讨论】:

    标签: javascript real-time rethinkdb voting deepstream.io


    【解决方案1】:

    好点子,让客户操纵投票可能效果不佳!

    我会使用rpc 来完成此操作,这样在浏览器中您可以让受信任的提供者代表用户增加记录。

    你需要做的三件事是:

    1. 通过浏览器请求 rpc
    2. 从 rpc 提供者(可以响应 rpc 的可信客户端)响应它
    3. 添加权限以拒绝非提供者更改记录的任何尝试

    代码如下所示:

    浏览器中的JS代码

    /**
    * Login to deepstream as Frank
    */
    var ds = deepstream( 'localhost:6020' ).login( { username: 'Frank'} );
    
    var voteText = $('.streaming-prices .vote');
    var name = 'vote';
    var record = ds.record.getRecord( name );
    
    $('#upvote_btn').click(function() {
        // on button click, increment the vote counts
        // set the record stored in the rethinkdb storage
        ds.rpc.make( 'upvote', {}, function( error, response ){
            //notify user when upvote succesfull
        });
    });
    
    record.subscribe('count', function( newVal ) {
        console.info( 'count updated, newVal: ', newVal);
        voteText.text(newVal);
    });
    

    处理投票的 rpc 提供者

    /**
    * Login to deepstream as Frank
    */
    var ds = deepstream( 'localhost:6021' ).login( { username: 'upvote-provider' } );
    
    var name = 'vote';
    var record = ds.record.getRecord( name );
    
    ds.rpc.provide( 'upvote', function( data, response ){
        record.set( 'count', record.get( 'count' ) + 1 );
        response.send();
    });
    

    服务器还应具有仅允许upvote-provider 更改投票的权限。

    canPerformAction: function( username, message, callback ) {
        /**
         * If the user is a provider, it has all permissions
         */
        if( username === 'upvote-provider' ) {
            callback( null, true );
        }
        /**
         * Otherwise the client request is valid unless it's trying to change the score
         */
         else {
            var messageObj = Deepstream.readMessage( message );
            var isAllowed = messageObj.name !== 'vote' || messageObj.isRead;
            var errorMessage = isAllowed ? null : 'Can\'t change votes via client, use \'upvote\' rpc instead';
            callback( errorMessage, isAllowed );
        }
    }
    

    【讨论】:

    • 谢谢,我回家后会尝试建议的方法,不胜感激
    猜你喜欢
    • 2011-02-26
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    相关资源
    最近更新 更多