分类 默认分类 下的文章

Laravel6 启动dusk时遇到JSON decoding of remote response failed

今天第一次使用Laravel Dusk来写UI测试。

按照文档安装好dusk,使用php artisan dusk尝试跑测试后,报了以下错误:

Facebook\WebDriver\Exception\WebDriverException: JSON decoding of remote response failed.
Error code: 4
The response: ''

搜索了一圈,在这个链接找到一个解决方法。需要先用./vendor/laravel/dusk/bin/chromedriver-mac-intel --port=9515这个命令启动chrome,再跑php artisan dusk才可以。(我用的是Intel版的mac,其他版本有对应的chrome driver)

我觉得很奇怪,dusk命令居然还要我手动启动chrome的吗?

后来试了一下关闭启动了的chromedriver,并在dusk命令前添加了sudo:sudo php artisan dusk
果然代码可以跑通了。

但我看chromedriver-mac-intel文件是-rwxr-xr-x,不应该启动不了啊?

在网上搜索了一圈,说要用php artisan dusk:chrome-driver --proxy=0.0.0.0:8888命令先安装chrome driver,但文件是存在的。太奇怪了。安装了之后,再跑php artisan dusk,现在报的错就不一样了:

Facebook\WebDriver\Exception\UnknownErrorException: unknown error: Chrome failed to start: exited abnormally.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location ./vendor/laravel/dusk/bin/chromedriver-mac-intel is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

在网上搜索了第二圈,说安装了之后要重启才行。俗话说重启大法好,那我就重启看看吧。

重启之后果然就好了……

docker初探

好吧,其实这个标题是假的。
我在不知不觉中已经用了很多次docker了。
但是docker的构建,编译和运行大部分是同事完成的。

还有很多docker的知识我还不是很懂,所以打算借此机会学习一下。
会参考一些教程网站,例如:

  1. Docker入门教程(一)介绍
  2. Docker中文社区站-Docker入门教程

首先,运行任何"docker"(容器),都需要两个步骤:

  1. 构建镜像
  2. 运行容器

整个过程可以简单地理解为写代码打包(构建镜像),双击在本地运行(运行容器)。
构建镜像可以理解为"docker"(容器)是编译型语言,类似Java,C/C++,需要先编译。
其次,编译完的可执行文件需要双击才能运行,光编译完没啥用,除了拿来发布。

镜像有什么用呢,其实就是自己打包好的环境。
现在我的笔记本(win)就因为我之前瞎鼓捣些项目,有些环境又不是很完善,整个环境有些乱了。
鼓捣完了之后,又不舍得卸载,而且还卸不干净。

如果你把你搭建好的环境打包放出去给别人下载,其他人就不用重复踩你踩过的坑了。
而且随用随下,用毕即弃。是不是听起来好像一次性餐具?但是这是电子世界,你丢弃一次性01串不会造成污染(用电的不算)。

好了,说了那么多废话,继续回到话题上来。

现在我们就先不讲构建镜像了。我们先用别人构建好的镜像。
先跑这个命令下载镜像:docker pull ubuntu
我此时下载的镜像是这样的,随版本更新,以下hash值会不一样。

Using default tag: latest
latest: Pulling from library/ubuntu
75c416ea735c: Pull complete
c6ff40b6d658: Pull complete
a7050fc1f338: Pull complete
f0ffb5cf6ba9: Pull complete
be232718519c: Pull complete
Digest: sha256:a0ee7647e24c8494f1cf6b94f1a3cd127f423268293c25d924fbe18fd82db5a4
Status: Downloaded newer image for ubuntu:latest

docker images就可以看到你下载过的镜像。

REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
ubuntu                 latest              d355ed3537e9        14 hours ago        119 MB

好,我们现在让它跑起来:docker run -it ubuntu bash
可以看到命令行变成root@4d3f61c27b6c:/#了。
这个时候,你可以敲任何ubuntu命令了。

这条命令的意思是,在ubuntu这个镜像上run(运行)bash这条命令。
-it呢,等于-i -t
-i就是Keep STDIN open even if not attached,就是交互模式。
-t就是Allocate a pseudo-TTY,分配一个虚拟TTY?
-t参数模拟ssh登陆容器(这个描述应该不准确),然后用-i参数来接受来自用户的输入`。

我尝试了一下,如果只有-i参数,那它会啥都不输出。
虽然是交互模式,但是没有tty,所以输出内容不会传输过来到宿主机。
如果只有-t参数,虽然有输出,但是无法接收来自用户的输入。
但是-it(或者-ti)就即能接收用户的输入,也可以显示容器的输出(这个描述应该也不准确)。

你大概已经折腾了一天,该睡觉了吧?
在linux里敲exit就可以退出bash。

咦?那我明天也运行docker run -it ubuntu bash就好了吗?
你可以试试啊~进入linux后,你会发现你昨天做的改动都没有了。
机子名也变了。敲exit退出。

在宿主机(安装了docker的机子)敲docker ps -a就可以看到,我们刚刚运行的容器已经结束了。

λ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
0e152599996f        ubuntu              "bash"              45 seconds ago      Exited (0) 1 second ago                        naughty_wilson
4d3f61c27b6c        ubuntu              "bash"              3 minutes ago       Exited (0) 2 minutes ago                       happy_shockley

这里的-a表示all,不带-a的情况下,只会显示正在运行的容器。

如果要它一直运行下去的话怎么办?
这里就先留个问题给读者。(其实是我要睡觉了)

Ubuntu升级内核

新买了个gigsgigscloud的vps搭mc服务器。
虽然ubuntu系统版本是16.04,但是内核版本居然只是2.6……
docker都跑不了。

升级内核步骤如下:
sudo apt-get install software-properties-common python-software-properties
sudo add-apt-repository ppa:kernel-ppa/ppa
apt-cache showpkg linux-headers找最新支持的版本
在我这里是4.4.0-59(好像也有4.8的)
重点是,两个headers,一个image(不是images)。两个headers中,一个带generic,另一个没带。
最后要加上--fix-missing
sudo apt-get install linux-headers-4.4.0-59 linux-headers-4.4.0-59-generic linux-images-4.4.0-59 --fix-missing
更新grub
sudo update-grub
在我这里运行这句的时候,报错/usr/sbin/grub-probe: error: failed to get canonical path of /dev/simfs.
居然在最后一步出现问题……死活更新不了内核,只能发工单。
客服回复说:OpenVZ下换不了内核,需要用KVM。
好吧,被坑了。
我去申请退款。

socket.io通信

春节放假了,打算把搁了很久的项目做了。

项目的来源是这样的:
虾米音乐把直播间功能砍掉了。
直播间就是播主放什么歌,观众也能跟着听的一个功能。
可以一起听歌的意思。

然后我就立了flag说要做个谷歌插件来实现被他砍掉的直播间功能。
主要功能就是在观众端同步执行播主进行的操作就好了。

于是开始写了。

准备
因为这个功能是实时性的,就想到用socket.io。
要用socket的话,要先安装node。
nodejs并不在ubuntu的默认源中,需要自行添加ppa再安装。

新建package.json文件,里面写{}。安装express包和socket包。
npm install --save express
npm install --save socket.io

安装完毕,再写个基本的端口监听和返回响应的功能,存为index.js

var app = require('express')();
var server = require('http').Server(app);

var listen_port = 9999;
server.listen( listen_port );

//route
app.get('/', function( request, response ){
    response.send('Hello world');
});

在这里监听的是9999端口。
输入node index.js就能启动服务器了。
目前没有在启动的时候输出内容,所以运行上面的命令后是没有任何输出内容的。
直接访问相应地址就可以看到运行结果。运行结果应该是会输出“Hello world”。

插件的撰写过程就另开一篇文章写吧。
插件实现的最主要功能就是往页面里插入代码。
插入的代码就是socket的客户端。

代码
好了,现在写客户端。

var socket_server, socket;

$(document).ready(function () {
    var btn = $('<button>').attr('id','test').css({
        'outline':'3px solid green',
        'position':'absolute',
        'top':'0',
        'left':'0',
    'width': '100px',
    'height': '30px'
    });
    $('#player-main').append(btn);

    socket_server = 'http://plamenatv.free.bg/up.html //socket地址
    socket = io( socket_server );

    $('#test').on('click', function(){
        socket.emit('player.pause', 'Amethyst'); //触发事件player.pause,发送数据为Amethyst
    });
});

与此同时,服务端也要相应的增加了。

...  //原来写的代码
io.on('connection', function( socket ){
    socket.on('player.pause', function( message ){  //监听事件
        console.log('Player paused ' + message + '.'); //把收到的消息打印出来
    });
});

[未解决]mac下./configure,C编译器无法创建可执行文件

pecl install redis未果,打算自己下载编译。
第一步phpize是可以执行的,但是到了第二步./configure就不行了。

$ ./configure
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for a sed that does not truncate output... /usr/local/opt/gnu-sed/libexec/gnubin/sed
checking for cc... cc
checking whether the C compiler works... no
configure: error: in `/Users/pires/codes/php-redis/redis-3.1.0':
configure: error: C compiler cannot create executables
See `config.log' for more details