sunnirvana

2143 经验值

第四节视频中的代码

route.php

...
Redis::publish('test-channel', json_encode($data));  <== 服务器端在test-channel上广播Redis信息
...

socket.js

...
redis.subscribe('test-channel');  <== 服务器端订阅Redis test-channel

redis.on('message', function(channel, message){  <== 服务器端监听Redis事件
    console.log(channel, message);
    io.emit(channel + ':' + JSON.parse(message).event, JSON.parse(message).data);  <== 服务器端广播socket.io事件
});
...

welcome.blade.php

...
<script>
            ready:function(){
                socket.on('test-channel:userMessage', function(data){  <== 客户端监听socket.io事件
                    this.users.push(data.first_name + ' ' + data.last_name);
                }.bind(this))
            }
</script>
...

这个过程应该是:[打开网页] -> [服务器端在test-channel上广播Redis信息] -> [服务器端订阅Redis test-channel] -> [服务器端监听Redis事件] -> [服务器端广播socket.io事件] -> [客户端监听socket.io事件]
对于一个打开的网页来说,它是监听者,当它加载时(刷新)他就是事件触发者。
所以当有多个网页打开时,刷新其中一个网页,它本身不会显示,而信息只能显示在其他的网页。

第二节视频中的代码:

index.html

...
<script>
    var socket = io();
    $('#messageForm').submit(function(){
        // send chat.message to the server
        socket.emit('chat.message', $('#message').val());    <== 客户端广播socket.io事件
        $('#message').val('');
        return false;
    });
 
    socket.on('chat.message', function(message){   <== 客户端监听socket.io事件
        console.log(message);
//        $('#messages').html('<li> ' + message + '</li>');
        $('#messages').append($('<li>').text(message));
    });
</script>
...

index.js

...
io.on('connection', function(socket){
    console.log('a user connect');
    // listening chat.message
    socket.on('chat.message', function(message){  <== 服务器端监听socket.io事件
        console.log('a new message: ' + message);
        // broadcast chat.message to all users connected to the server.
        io.emit('chat.message', message);  <== 服务器端广播socket.io事件
    });
});
...

这个过程应该是: [打开网页] -> [客户端广播socket.io事件] -> [服务器端监听socket.io事件] -> [服务器端广播socket.io事件] -> [客户端监听socket.io事件]
对于一个打开的网页来说,它既是广播者又是订阅者。
所以当打开多个网页的时候,刷新不同的网页,会在每个网页上都显示信息。

在这节视频的最后(13:08),教主打开了两个网页,来测试结果。
我的理解是,刷新一个网页后,两个网页应该同时会显示Jelly,不过实际结果是被刷新的网页(视频中的左侧)中Jelly最后是消失了。这是为什么 ?

另外一个问题是,在这节课中,应该是有两层数据共享,或者说broadcast / subscribe的,
第一层是:Redis, 用于Laravel和Socket.js (node) 共享数据;
另一层是:Socket.io的服务端和客户端之间的数据传递。
我的理解对吗?

谢谢!

有所有字段信息的数据,需要重新组织出表和字段的关系,并且字段是按照要求排序的。

原始数据中

“table_name”:字段所属表
“field_name“ : 字段名
“field_col_num":字段排序号

期待输出的结果是

{
    "table_name" : [
        "field_name",
        "field_name",        
        ....
    ]
}

测试数据如下:

原始数据:

[
{
"table_name": "dp",
"field_name": "dpcryptfeat",
"field_col_num": "6"
},
{
"table_name": "dp",
"field_name": "dppath",
"field_col_num": "4"
},
{
"table_name": "dp",
"field_name": "dpauthfeat",
"field_col_num": "5"
},
{
"table_name": "dp",
"field_name": "dpnick",
"field_col_num": "3"
},
{
"table_name": "icc",
"field_name": "iccbufsizeprot",
"field_col_num": "13"
},
{
"table_name": "icc",
"field_name": "iccmech",
"field_col_num": "5"
},
{
"table_name": "icc",
"field_name": "iccnick",
"field_col_num": "3"
},
{
"table_name": "icc",
"field_name": "iccprocmanager",
"field_col_num": "8"
},
{
"table_name": "icc",
"field_name": "iccdesc",
"field_col_num": "4"
},
{
"table_name": "icc",
"field_name": "iccprot",
"field_col_num": "6"
},
{
"table_name": "icc",
"field_name": "iccformatprot",
"field_col_num": "14"
}
]

输出结果:

{
"dp": [
"dpnick",
"dppath",
"dpauthfeat",
"dpcryptfeat"
],
"icc": [
"iccnick",
"iccdesc",
"iccmech",
"iccprot",
"iccprocmanager",
"iccbufsizeprot",
"iccformatprot"
]
}

SQLite 没有 left 函数,使用PDO的 sqliteCreateFunction 来创建自定义函数时,发现创建成功,但是无论如何都在SQL语句中不能使用,总是报错 "SQLSTATE[HY000]: General error: 1 near "(": syntax error"

DB::connection('sqlite')->getPdo()->sqliteCreateFunction('left', function($str, $len){    
    if ($str != '') {        
         return substr($str, 0, $len);    
    }    
    return '';
});

几番调试之后,发现 left 是 SQLite 的保留字(LEFT JOIN),所以只要换名字,例如 myLeft 就可以了。

另外,left 的功能可以使用SQLite中的substr函数来代替。

终于有时间消化之前的视频了

@justtest 谢谢答案,真符合我的需求。还有两个问题:

  1. 下面这句笔误了吧?
    if ($sqlite = static::$sqliteDatabase) {

  2. app()['config]->set 类似这种接口有文档可以参考吗?还是要直接看源码?