我已经开始使用Laravel 5.1并且它非常棒,只是想通过使用NodeJs作为服务器来玩新的“广播事件”功能,而Redis作为驱动程序遵循指南:http://blog.nedex.io/laravel-5-1-broadcasting-events-using-redis-driver-socket-io/ 。当我触发一个实现ShouldBroadcast接口的事件时,我收到一个错误: “从服务器读取行时出错。[tcp://127.0.0.1:4365]”
4365 - 是运行服务器的端口(在该端口中侦听)。你知道为什么会这样吗?
我还尝试直接使用Redis:
$redis = Redis::connection();
$redis->publish('test-channel', 'msg');
得到相同的结果,“从服务器读取行时出错。[tcp://127.0.0.1:4365]”。
socket.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('test-channel', function(err, count) {
});
redis.on('message', function(channel, message) {
console.log('Message Recieved: ' + message);
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.payload);
});
http.listen(4365, function(){
console.log('Listening on Port 4365');
});
设置\ database.php中:
'redis' => [
'cluster' => false,
'default' => [
'host' => '127.0.0.1',
'port' => 4365,
'database' => 0,
'timeout' => 100,
],
],
尝试更改defulat超时,将其设置为0,-1或> 10 还尝试在php.ini中禁用Xdebug,问题仍然存在。
我对代码进行了一些调试,试图解决可能导致此问题的原因并且在类中失败:Predis \ Connection \ StreamConnection
public function read()
{
$socket = $this->getResource();
$chunk = fgets($socket);
if ($chunk === false || $chunk === '') {
$this->onConnectionError('Error while reading line from the server.');
}
...
大块是假的为什么?
为什么redis客户端试图从服务器读取数据,因为我理解它应该“发布”到服务器的数据,意味着它应该写(广播)不读取..
答案 0 :(得分:2)
我认为对Redis的含义存在误解。
Redis是一个开源,BSD许可,高级键值缓存和商店。
它经常用于进程间通信(IPC),它有很好的PUBLISH和SUBSCRIBE命令。
因此,使用Laravel和Node,Redis可以在Node和Laravel的永久运行过程之间进行通信。 Laravel将其事件发布到Redis,Node订阅了Redis的特定频道。在这里,可以通过套接字连接发出消息,很可能是通道名称相同。
要使这一切正常运行,您必须执行以下操作(very well explained in the docs):
<%@ page contentType="text/html; charset=iso-8859-1" language="java"
import="java.sql.* "%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>Films Example: JSP</title>
</head>
<body bgcolor="white">
<div>
<h1>Filmworld</h1>
<table border=1>
<tr>
<td>imdbID</td>
<td>name</td>
<td>year</td>
<td>rating</td>
<td>votes</td>
<td>runtime</td>
<td>actors</td>
<td>genres</td>
<td>directors</td>
</tr>
<%
try {
String driver = "org.postgresql.Driver";
String url = "jdbc:postgresql://localhost:5432/movie";
String username = "postgres";
String password = "cemcan";
String myDataField = null;
String myQuery = "SELECT * FROM movie";
Connection myConnection = null;
PreparedStatement myPreparedStatement = null;
ResultSet myResultSet = null;
Class.forName(driver).newInstance();
myConnection = DriverManager.getConnection(url, username, password);
myPreparedStatement = myConnection.prepareStatement(myQuery);
myResultSet = myPreparedStatement.executeQuery();
out.println("<table border=1>");
while (myResultSet.next()) {
String imdbID = myResultSet.getString("imdbID");
String name = myResultSet.getString("name");
int year = myResultSet.getInt("year");
double rating = myResultSet.getDouble("rating");
int votes = myResultSet.getInt("votes");
int runtime = myResultSet.getInt("runtime");
String directors = myResultSet.getString("directors");
out.println("<tr><td>" + imdbID + "</td><td>" + name + "</td><td>" + year + "</td><td>" + rating
+ "</td><td>" + votes + "</td> <td>" + runtime + "</td> <td>" + directors + "</td> </tr>");
}
out.println("</table>");
myConnection.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException ex) {
out.print("SQLException: " + ex.getMessage());
out.print("SQLState: " + ex.getSQLState());
out.print("VendorError: " + ex.getErrorCode());
}
%>
</table>
</div>
</body>
</html>
。也许它是一个Bug?Redis::publish('test-channel', json_encode(['foo' => 'bar']));
的事件。出于测试目的,您可以使用:ShouldBroadcast
现在是切换到Node的时候了:
您的socket.js代码看起来不错,假设Redis在端口6379上。如果Node在本地运行,您可以在浏览器中连接到您的节点服务器,如下所示:Redis::publish('test-channel', json_encode(['foo' => 'bar']));
。
这是我在前端和后端测试Node和Socket.io的代码:
<强> socket.js 强>
localhost:4365
<强>的index.html 强>
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
redis.subscribe('test-channel', function () {
console.log('Redis: test-channel subscribed');
});
redis.on('message', function(channel, message) {
console.log('Redis: Message on ' + channel + ' received!');
console.log(message);
message = JSON.parse(message);
io.emit(channel, message.payload)
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
我希望这有点帮助:)
答案 1 :(得分:1)
如果在x秒(不是直接)之后收到上述错误,则需要在database.php配置文件中设置读写超时。
如果要将其作为后台任务运行,则以下内容将起作用:
'redis' => [
'cluster' => false,
'default' => [
'host' => '127.0.0.1',
'port' => '6379',
'database' => 0,
'read_write_timeout' => -1
],
],