Write the Code. Change the World.

1月 26

完成了注册和登录,现在来完成完整邮箱验证

参考

https://blog.vini123.com/288

https://blog.vini123.com/333

按照上述参考操作,先将 User 模型实现 MustVerifyEmail,再修改路由,加入中间件 verified

Route::namespace('Web')->middleware(['verified'])->group(function() {

    Route::get('/', 'PageController@home')->name('home');

    Route::get('search', 'PageController@search')->name('search');

    Route::get('/users/{user}', 'UserController@index')->name('users.show');

    Route::group(['middleware' => 'auth'], function() {
        Route::get('/users/{user}/edit', 'UserController@edit')->name('users.edit');
    });
});

访问首页,发现会自动跳转到验证邮箱页面。然后点击重新发送验证。会发现有下边的报错:

Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required
 "

这个是 email 相关的配置没好,我们可以使用 qq 邮箱、163邮箱等进行 SMTP 发送邮件。以 qq 邮箱来说,首先得去自己的 qq 邮箱里去申请开通。这里直接列出邮箱的配置数据。

vim .env

# 填充好下边的配置
MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=xxx@xxxx.com
MAIL_PASSWORD=xxxxx
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=xxxx@xxxx.com
MAIL_FROM_NAME=xxxxxx

当这些配置好了,再发送时,提示 新的验证链接已发送到您的 E-mail。 邮件已经发送。点击,跳转验证。

如果想验证成功后出现提示,可以在 EventServiceProvider中增加:

        \Illuminate\Auth\Events\Verified::class => [
            \App\Listeners\EmailVerified::class,
        ],

然后,自定义 mailVerified 类。添加好上边的,再执行 php artisan event:generate 会自动生成,然后填充方法。

    public function handle(Verified $event)
    {
        // 会话里闪存认证成功后的消息提醒
        session()->flash('success', '邮箱验证成功 ^_^');
    }

之前,弄的样式以及 layouts/app.blade.php 有问题,需要稍微修改。这里懒的弄了。下一步,权限管理,使用 spatie/laravel-permission

阅读全文 >>

1月 25

上边完成了基本布局,发现某些 js,css缺失。这个时候,需要补进来。然后,完成服务端的注册登录逻辑,以及 gee 验证。

修补

加入以下文件

static/style/css/nprogress.css
static/style/css/nprogress.min.css

static/style/js/fn.js
static/style/js/gt.js
static/style/js/nprogress.min.js

部分调整

  1. 将 nprogress.min.js 和 app.js 的加载顺序更换一下。因为 app.js 中会使用到 nprogress 的封装
git add .
git commit -m '修复引入js,css不存在的bug'

认证脚手架

php artisan ui:auth

# 因为之前已经有了 layouts 相关的文件,这个时候会提示是否要覆盖,输入 no 回车。这个时候,会补入和修改相关的文件

# 查看变更的文件
git status 

# 删掉其他新增文件,只保留 resources/views/auth/ 下的文件
# web.php  路由也处理一下。之前就已经好了,这次注入是重复的,可以删掉重复的部分。

做好上边这些,然后开始修改 user 表的迁移文件,以及将 User模型移动到 app\Models\ 下。

阅读全文 >>

1月 19

构建 bootstrap 框架,并定制好基本布局

composer require laravel/ui --dev

php artisan ui bootstrap

以上命令做了以下事情:

  1. 在 npm 依赖配置文件 package.json 中引入 bootstrap、jquery、popper.js 作为依赖;
  2. 修改 resources/js/bootstrap.js ,在此文件中初始化 Bootstrap UI 框架的 JS 部分;
  3. 修改 resources/sass/app.scss 以加载 Bootstrap 的样式文件;
  4. 新增 resources/sass/_variables.scss 样式配置文件。

运行 Laravel Mix

Laravel Mix 一款前端任务自动化管理工具,使用了工作流的模式对制定好的任务依次执行。Mix 提供了简洁流畅的 API,让你能够为你的 Laravel 应用定义 Webpack 编译任务。Mix 支持许多常见的 CSS 与 JavaScript 预处理器,通过简单的调用,你可以轻松地管理前端资源。

使用 Mix 很简单,首先你需要使用以下命令安装 npm 依赖即可。我们将使用 Yarn 来安装依赖,在这之前,因为国内的网络原因,我们还需为 NPM 和 Yarn 配置安装加速:

npm config set registry=https://registry.npm.taobao.org
yarn config set registry https://registry.npm.taobao.org

# 查看镜像
npm get registry 
yarn config get registry

yarn install

yarn run watch-poll

下边进行基础布局

阅读全文 >>

1月 19

从零开始构建 laravel 项目

包裹以下功能:

  1. web 页面(可能是商城,可能是论坛,可能是其他)
  2. 接口功能(一套接口(jwt),提供给 app,小程序 或其他)
  3. 后台功能 (不再使用 layui admin ,使用 ant design pro。权限控制,laravel 自己的权限控制很好,ant design pro 不熟,不知两边的权限能否融洽。就是只使用服务端的权限,不去耦合 antdesignpro 的权限)
  4. 额外。 微信授权、站点地图、elastsearch、定时任务、swoole等。

开始

开发环境依然是 homestead。虽然 docker 很火热, 但总用不好。还有,如果真是线上环境,宁愿一个一个去编译安装所用软件(个数不多)。因为不熟悉,所以不敢放心去使用。

homestead 配置域名:admin.com

laravel 版本为最新版本 6.8.*

# 创建 laravel 6.8 项目
composer create-project laravel/laravel --prefer-dist admin.com "6.8.*"

cd admin.com

# 去掉原本的 readme,添加简单的 readme
rm -rf README.md

echo 'laravel 6.8 initialize' >> Readme.md

# 初始化 git
git init

# 添加,并 commit
git add .

git commit -m 'laravel 6.8 initialize'

为了保证代码风格,安装使用 editorcofig 。配置文件 laravel 项目里边已经有了再稍微改一点点。如下,保存提交版本。

修改根目录下的 .editorconfig

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.yml]
indent_size = 2

[*.{js,html,blade.php,css,scss}]
indent_style = space
indent_size = 2

然后提交版本:

git add .
git commit -m '增加 editorconfig 配置'

修改时区以及语言版本

# vim config/app.php

'timezone' => 'Asia/Shanghai',

'locale' => 'zh-CN',

# git
git add .

git commit -m '设置时区以及默认语言版本'

添加辅助函数

# 在 app 目录下,添加 helpers.php 文件,辅助函数都放在该文件里。
touch app/helpers.php

# 修改 composer.json,让 autoload 的时候载入辅助函数

{
    ...

    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "files": [
            "app/helpers.php"
        ]
    }
    ...
}

# 重新加载文件
composer dump-autoload

git提交

git add .

git commit -m '新增辅助函数文件'

现在 helpers.php 文件还是空的,但后续可以添加你需要的。比如 curl 等。

阅读全文 >>

1月 18

站点地图有助于 seo 优化,一般站点都会制作站点地图。 Laravel 项目,有制作站点地图的插件 Laravelium-sitemap。拿来用即可。

laravelium-sitemap wiki

看文档,根据不同的 laravel 版本安装不同的包。

了解点

  1. 可以直接展示站点地图或分包展示地图。也就是直接 xml 或 sitemap index。

做一做

composer require laravelium/sitemap

php artisan vendor:publish --provider="Laravelium\Sitemap\SitemapServiceProvider"
  1. 可以缓存。不是每次请求都要生一个。

  2. 可以添加图片,视频等资源。

实践产品

逻辑里边,两种展示方式都添加了。只是选择了直接使用 xml
https://www.yuepaibao.net/sitemap.xml

阅读全文 >>

1月 11

从零开始构建 node 项目

拥有 node,开始从零构建 node 项目吧

mkdir nodeservice

cd nodeservice

npm init

# 输入项目介绍,关键词,auth这些,一路回车,yes,成功创建 package.json 文件。
# 此时仅有该文件

然后按照需要,安装必须用到的包。少了,后边可以继续安装。

npm install express

npm install lodash

npm install moment

npm install mysql

npm install redis

npm install ioredis

npm install request

npm install socket.io

npm install socket.io-redis

npm install socketio-jwt

npm install async

npm install url

npm install jsonwebtoken

npm install bluebird

npm install china-time

npm install winston

npm install mqtt

然后创建 server.js

touch server.js

参考

https://blog.csdn.net/u013165804/article/details/80568626

https://www.jianshu.com/p/5690ebdd18fa

兜底node.js异常

unhandledRejection

阅读全文 >>

1月 11

为了早点体验到 ant design pro 的页面,注释了部分配置,显示出了 welcome 页面。可是当你刷新页面时候,到你面前的就是 404 。这里,就要先解决 404 问题。

Ant Design Pro 使用的 Umi 支持两种路由方式:browserHistoryhashHistory。默认就是 browserHistory。这样漂亮好看。而默认就是这种方式。具体请看:

https://pro.ant.design/docs/deploy-cn#%E5%89%8D%E7%AB%AF%E8%B7%AF%E7%94%B1%E4%B8%8E%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%9A%84%E7%BB%93%E5%90%88

虽然这种方式漂亮好看。可对于解析认识是个问题。需要服务端进行处理。因为只使用过 nginx,这里就说下 nginx 下的解决方法。

找到对应的 nginx 的配置文件,并修改文件。

如果 ant design pro 编译后的文件直接在根目录下,可以在配置文件中增加

    location /  {
        index index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

如果 ant design pro 编译后的文件不再根目录下(比如在 dashboard 下),可以在配置文件中增加

    location /dashboard  {
        index index.html index.htm;
        try_files $uri $uri/ /dashboard/index.html;
    }

然后保存重启 nginx ,再刷新页面,发现不再是 404 了。

nginx -s reload

homestead 中,虚拟机里的配置文件在 /etc/nginx/sites-available/ 下,可以单独修改,重启。但这样重启后,会再生。清理的脚步在本地的 Homesteadscripts/clear-nginx.sh 中。如果单独对某个域名处理,最好在本地的 scripts/site-types/ 下新建配置,然后 Homestead.yml 文件中,对具体域名指定配置。

多的话就不说了,具体还是 nginx 的修改配置。 至于 nginx 的 try_files 是什么意思了,可以了解下。

try_files 的核心目的就是替代。比如,

location /dashboard  {
    index index.html index.htm;
    try_files $uri $uri/ /index.php?q=$uri&$args;
}

以 根目录(对应站点的根目录)下的 dashboard 目录为参照,先查找第一个节点,看文件是否存在,如果不存在再看文件夹(有斜杠)是否存在,如果再不存在,就指向到第三个参数。

比如具体的 url 是这样的。

https://www.mlxiu.com/dashboard/love

它会先检查 love 这个文件是否存在,如果不存在 love 这个文件则检查 love 这个文件夹。当然,文件的后缀,上边已先列出。

具体看 nginx 的 try_files

https://blog.csdn.net/a519640026/article/details/9138329

https://www.cnblogs.com/boundless-sky/p/9459775.html

阅读全文 >>

1月 10

准备好基础框架后,就可以开始准备起接口了。准备最最基础的登录注册接口。

需要做以下处理:

  1. 准备 user 表的迁移文件。
  2. 准备 jwt
  3. 准备好路由以及文件结构
  4. 相关注册逻辑。

先准备 user 表的迁移文件

默认就有了 user 表的迁移,我们直接修改它就好。

$table->bigIncrements('id');
$table->string('account', 16)->unique();
$table->string('password');
$table->unsignedInteger('viewid')->unique();
$table->string('phone', 16)->unique();
$table->string('email')->nullable();
$table->string('nickname');
$table->string('avatar')->default('app/public/upload/image/avatar/default.jpg');
$table->string('signture')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->rememberToken();
$table->nullableTimestamps();

# 执行迁移
php artisan migrate

创建 Models 目录。

# App 目录下创建 Models 文件夹,并将 User 模型移动到该文件夹下
mkdir App/Models
mv App/User.php App/Models/User.php

再修改 User 的命名空间,并将整个框架的 User 的命名空间变更。

安装 jwt

# 安装
composer require tymon/jwt-auth:1.0.0-rc.5

# 生成 jwt 的 secret
php artisan jwt:secret

jwt-auth 有两个重要的参数,可以在 .env 中进行设置
JWT_TTL 生成的 token 在多少分钟后过期,默认 60 分钟
JWT_REFRESH_TTL 生成的 token,在多少分钟内,可以刷新获取一个新 token,默认 20160 分钟,14 天。

这里需要理解一下 JWT 的过期和刷新机制,过期很好理解,超过了这个时间,token 就无效了。刷新时间一般比过期时间长,只要在这个刷新时间内,即使 token 过期了, 依然可以换取一个新的 token,以达到应用长期可用,不需要重新登录的目的。

# 编辑 .env 增加 jwt 的过期配置和刷新配置
vim .env
# 增加下边两个配置
JWT_TTL= 10080
JWT_REFRESH_TTL=20160

修改完善 User 模型,使其继承 Tymon\JWTAuth\Contracts\JWTSubject 接口,并实现接口的两个方法 getJWTIdentifier()getJWTCustomClaims()

于是 User 模型中的类容为:

<?php

namespace App\Models;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;


    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }

    protected $fillable = [
        'account', 'password', 'viewid', 'phone', 'email', 'nickname', 'avatar', 'signture'
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

我们启动 tinker,先创建一个用户,再尝试获取 jwt token。

# 启动 tinker
php artisan tinker

use App\Models\User;
use Hash;
use Auth;

$user = [
    'account' => '1367163xxxx',
    'password' => Hash::make('123456'),
    'phone' => '1367163xxxx',
    'nickname' => '七月羽歌',
    'signture' => '美的事物是永恒的喜悦'
];

# 创建用户
User::create($data);

# 获取用户
$user = User::first();

# 获取 token
Auth::guard('api')->login($user);

新建用户登录注册控制器

# 创建控制器
php artisan make:controller Api/AuthorizationsController

# 创建 request
php artisan make:request Api/AuthorizationRequest

然后编辑 request

<?php

namespace App\Http\Requests\Api;

use Illuminate\Foundation\Http\FormRequest;

class AuthorizationRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'account' => 'required|regex:/^1[1-9]\d{9}$/',
            'password' => 'required|alpha_dash|min:6'
        ];
    }
}

控制器代码

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\AuthorizationRequest;
use Illuminate\Auth\AuthenticationException;
use Auth;

class AuthorizationsController extends Controller
{
    public function login(AuthorizationRequest $request)
    {
        $data = $request->only(['account', 'password']);

        if (!$token = Auth::guard('api')->attempt($data)) {
            throw new AuthenticationException('用户名或密码错误');
        }

        return $this->respondWithToken($token)->setStatusCode(200);
    }

    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }
}

路由

Route::namespace('Api')->group(function () {
    Route::post('authorizations/login', 'AuthorizationsController@login')->name('api.authorizations.login');
});

然后使用 postman 测试下

登录好了,下一步就处理 ant design pro 框架。构建基础的功能以及去掉不需要的功能,美化页面。

有用的参考

如果多端,多表授权可以点这里

https://www.jianshu.com/p/344c5e540eaa

https://www.cnblogs.com/freely/p/10874297.html

https://www.cnblogs.com/lihuijuan/p/11242976.html

阅读全文 >>

1月 09

laravel 好用, ant design pro 不仅好用还好看。那么,laravel + ant design pro 做出来的项目也会很好用,很好看。

创建初始化 laravel 项目以及 ant design pro 项目

先创建 laravel 项目

# 创建 最新版本的 laravel 项目,并且指定项目文件名为 lreact.com
composer create-project laravel/laravel=6.* --prefer-dist lreact.com

# 删除原本的 readme
rm -rf README.md

# 使用新的 readme,简洁
echo '### Laravel 6.* initialize' >> Readme.md

# 初始化 git 仓库
git init
git add .
git commit -m 'Laravel 6.* initialize'

再创建 ant design pro 项目

在 `laravel` 的 `resources` 目录下,新建文件夹 `antdesign`
cd resources

mkdir antdesign

npm create umi
# 依次选择 ant design pro -> javascript

# 当前版本 v4

git add .

git commit -m 'ant design pro v4 initialize'

npm install

安装完成后,需要稍微修改,并打包

部署请参考 https://pro.ant.design/docs/deploy-cn

# 修改输出目录(antdesign 目录下)
vim config/config.js

# 添加指定目录 base 以及 publicPath

export default {
  base: '/dashboard/',
  publicPath: '/dashboard/',
  plugins,
  hash: false,

# 编译
npm run build

# 将打包好的文件复制到 laravel 的 public 目录
mv dist ../../public/dashboard

# 访问站点
https://www.lrect.com/dashboard

能正常访问,但是授权登录错误。先到这来。

如果你不想每次都移来移去,可以在 config/config.js 里追加配置 outputPath
参考

于是,配置为

export default {
  base: '/dashboard/',
  publicPath: '/dashboard/',
  outputPath: '../../public/dashboard',
  plugins,
  hash: false,

再打包。文件就会打包到 laravel 项目下的 public 下的 dashboard 目录下。

修改 request

ant design pro 的请求都放在 services 下。在这里你可以定义和修改请求。但,这里的请求用的是 umi-request, 而这里对 umi-request 的引用放在 utils/request.js 中。这里你可以添加 header,加入拦截器等等。请看 umi-request 文档。

https://github.com/umijs/umi-request/blob/master/README_zh-CN.md

这里添加空的拦截器(request,response),还有添加请求前缀。完整的 request.js 如下。后边,会对拦截器进一步完善。

/**
 * request 网络请求工具
 * 更详细的 api 文档: https://github.com/umijs/umi-request
 */
import { extend } from 'umi-request';
import { notification } from 'antd';
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。',
};
/**
 * 异常处理程序
 */

const errorHandler = error => {
  const { response } = error;

  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;
    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  }

  return response;
};

/**
 * 配置request请求时的默认参数
 */
const request = extend({
  prefix: '/dashboard',
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

// request拦截器, 改变url 或 options.
request.interceptors.request.use(async (url, options) => {
  const headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  };

  return (
    {
      url: url,
      options: { ...options, headers: headers },
    }
  );
})

// response拦截器, 处理response
request.interceptors.response.use((response, options) => {
  return response;
});

export default request;

到目前为止,输出目录,接口前缀,都是手动写的。分别写在了三个地方。如果想修改,必须得每个地方改一次。如果定义一个常量,直接使用常量不就好了么。下边进行常量定义。不过,定义了常量,那就必须保证你的需求里这三个地方的值是一样的。

定义常量,方便输出以及接口调用

在 config/config.js 中,定义常量 BASE , 设置好值。

const BASE = '/dashboard';

然后在 define 中进行注册该值。只有注册了,其他 js 才能访问的到,并且不需要加 window,请看这里文档。
https://pro.ant.design/docs/environment-variables-cn#%E5%A4%84%E7%90%86%E5%9C%A8-lint-%E4%B8%AD%E7%9A%84%E6%8A%A5%E9%94%99

于是 config/config.js 是这样

const BASE = '/dashboard';
…
export default {
  base: BASE,
  publicPath: `${BASE}/`,
  outputPath: `../../public/${BASE}/`,
  plugins,
  hash: false,
  targets: {
    ie: 11,
  },

…

utils/request.js 是这样

const request = extend({
  prefix: BASE,
  errorHandler,
  // 默认错误处理
  credentials: 'include', // 默认请求是否带上cookie
});

好了,提交 git 暂时先到这一步。

git add .

git commit -m '定义BASE作为项的输出路径和Api前缀'

最后又多一句,还是可以使用 npm start 进行奔跑的。

可参考

https://pro.ant.design/docs/getting-started-cn

https://www.yuque.com/yuxuanbeishui/zog1rm

https://learnku.com/articles/32218

https://umijs.org/zh/config/#uglifyjsoptions

https://www.codercto.com/a/26106.html

阅读全文 >>

1月 03

socket.io 默认支持断开重连。可经常断开长连也很不好。短时间内(比如一分钟)断开重连这种现象,很容易观察到,并且可以观察到时间都很准时,每经过某个时间就会断开然后重连。

遇到这个现象,该怎么处理呢。如果熟悉 socket.io 的机制,可能想到心跳问题。这里先跳过。

遇到这个现象 ,可能你会找服务端的原因。是 nginx 出问题了,还是实现 socket.io 的服务出现问题了。(socket.io 是 websocket 的包装版)

  1. 观察 nginx,因为 nginx 的代码最少。发现 nginx timeout 都注释掉了。
# proxy_connect_timeout 60s;
# proxy_send_timeout 60s;
# proxy_read_timeout: Nginx will close the connection if the proxied server does not send data to Nginx in 60 seconds; At the same time, this close behavior is also affected by heartbeat setting of Swoole.
# proxy_read_timeout 60s;
  1. 分析框架源码,这个是最漫长,和可能性大的。毕竟用到别人的框架。这里使用 swoole + laravels + websocket 的 socket.io 的封装。找了好久也没找到问题。

  2. 找不到具体原因,然后去看 socket.io 的文档。才发现,心跳没发送是一个原因。

https://socket.io/docs/server-api/#new-Server-httpServer-options

重述具体现象

前端页面连接好 socket.io 后,如果前端不发送任何消息,60 秒内,服务端就会断开服务。然后重连。如果在 60 秒之内,你有发送消息,这个断开时间就会延长。直到你不发消息后的 60 秒。那如果这样,利用 socket.io 的心跳不就解决了。可是,从始至终,都没看见过发送过心跳。原来是服务端设置的心跳时间太长了,远远超过了 60 秒。也就是心跳还没来得及发,服务端就已经断开了,前端就已经又重连了。既然这样,那控制心跳时间小于 60 秒不就好了。

既然是一种方法,那么前端 socket.io 怎么发送这个心跳呢。

前端连接好服务端后,服务端会推送一个消息下来,这个消息包裹以下信息:

0{"sid":"NWUwZWY4NzBiYjk1OQ==","upgrades":[],"pingInterval":44000,"pingTimeout":36000}

就是以 pingInterval 这个频率来发送心跳。 pingInterval 要大于 pingTimeout。 这样就可以很直接的看到心跳的间隔。修改服务端代码,onOpen 的时候,推送这个消息过来就好,并 pingInterval 是正确的值。

心跳就是 ping pong。一来一回,建立起来就好。

末了

socket.io 是 websocket 的封装版,就是在 websocket 上加入了约定好的算法以及计算,来实现 socket.io 的这种连接方式。

上边虽然解决了不再一分钟断开又重连。可是这个心跳频率还是有点高。因为上边提到的一分钟就断开,导致没办法把心跳设置大一点。这个问题需要处理。还是得去了解源码,进一步分析吧。

阅读全文 >>