...
Redis::publish('test-channel', json_encode($data)); <== 服务器端在test-channel上广播Redis信息
...
...
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事件
});
...
...
<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事件]
对于一个打开的网页来说,它是监听者,当它加载时(刷新)他就是事件触发者。
所以当有多个网页打开时,刷新其中一个网页,它本身不会显示,而信息只能显示在其他的网页。
...
<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>
...
...
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的服务端和客户端之间的数据传递。
我的理解对吗?
谢谢!
二位真的太厉害了!
这样的话,field没有排序
有所有字段信息的数据,需要重新组织出表和字段的关系,并且字段是按照要求排序的。
原始数据中
“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 谢谢答案,真符合我的需求。还有两个问题:
下面这句笔误了吧?
if ($sqlite = static::$sqliteDatabase) {
app()['config]->set 类似这种接口有文档可以参考吗?还是要直接看源码?