nonocast

Stay Hungry, Stay Foolish.

RFC 6455笔记

No comments

RFC 6455: http://tools.ietf.org/html/rfc6455

  • The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model(同源策略) commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing,layered over TCP. The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers.
  • WebSocket的版本历程,
       +--------+-----------------------------------------+----------+
       |Version |                Reference                |  Status  |
       | Number |                                         |          |
       +--------+-----------------------------------------+----------+
       | 0      + draft-ietf-hybi-thewebsocketprotocol-00 | Interim  |
       +--------+-----------------------------------------+----------+
       | 1      + draft-ietf-hybi-thewebsocketprotocol-01 | Interim  |
       +--------+-----------------------------------------+----------+
       | 2      + draft-ietf-hybi-thewebsocketprotocol-02 | Interim  |
       +--------+-----------------------------------------+----------+
       | 3      + draft-ietf-hybi-thewebsocketprotocol-03 | Interim  |
       +--------+-----------------------------------------+----------+
       | 4      + draft-ietf-hybi-thewebsocketprotocol-04 | Interim  |
       +--------+-----------------------------------------+----------+
       | 5      + draft-ietf-hybi-thewebsocketprotocol-05 | Interim  |
       +--------+-----------------------------------------+----------+
       | 6      + draft-ietf-hybi-thewebsocketprotocol-06 | Interim  |
       +--------+-----------------------------------------+----------+
       | 7      + draft-ietf-hybi-thewebsocketprotocol-07 | Interim  |
       +--------+-----------------------------------------+----------+
       | 8      + draft-ietf-hybi-thewebsocketprotocol-08 | Interim  |
       +--------+-----------------------------------------+----------+
       | 9      +                Reserved                 |          |
       +--------+-----------------------------------------+----------+
       | 10     +                Reserved                 |          |
       +--------+-----------------------------------------+----------+
       | 11     +                Reserved                 |          |
       +--------+-----------------------------------------+----------+
       | 12     +                Reserved                 |          |
       +--------+-----------------------------------------+----------+
       | 13     +                RFC 6455                 | Standard |
       +--------+-----------------------------------------+----------+
    

    如上表所见,RFC 6455已经是正式版本,也是整个草案的第十个版本,网上也有用人hybi09,hybi10来表示RFC 6455,知道一下就OK了。

  • 整个WebSocket协议分为2个阶段,先握手,握手成功后升级为WebSocket开始通信,原文描述: After a successful handshake, clients and servers transfer data back and forth in conceptual units referred to in ths specification as "message". On the wire, a message is composed of one or more frames.
  • A frame has an associated type. Each frame belonging to the same message contains the same type of data. Broadly speaking, there are types for texture data(UTF-8), binary data and control frames. This version of the protocol defines six frame types and leaves ten reserved for future use.
  • The handshake from the client looks as follows:
    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13
    

    其中Leading Line + Request Line符合HTTP[RFC2612],首先由client发起请求升级为WebSocket协议连接,Host区分网站(domain)这个不用解释了,而/chat则区分同站点中不同的websocket域,即同一站点内允许多个websocket server。Upgrade+Connection+Sec-WebSocket-Key则是向server申请提升。
    其中Sec-WebSocket-Key为base64编码,此key需要验证后续response中的Sec-WebSocket-Accept是否匹配。
    而Sec-WebSocket-Protocol则是应用协议,这个看程序了,协议本身不关心。

  • The handshake from the server looks as follows:
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat
    

    server回复就简单很多,如果提交上来又Upgrade+Connection+Sec-WebSocket-Key则将此Key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"然后计算此字符串的SHA-1通过base64返回给client。
    回复的Leading line如果同意提升则status code为101,其余都认为失败。一旦101后双方就可以通信了。

  • WebSocket是基于TCP的,仅依赖HTTP进行握手,升级后脱离HTTP协议,WebSocket协议允许和HTTP共用80端口,或者同时共用443。
  • WebSocket URI定义了2种scheme,如下,
    • ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
    • wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]

    ws端口默认80,wss默认443。

continue reading...

第一次用'母语'和SQLite打交道,真是又紧张又激动。对照SQLite权威指南发现网上除了官网本身的文档其他都多少有点出入,尽量看官方文档,你懂的。

先快速浏览一下C API,List Of SQLite Functions,正如文档所说,从开始的5个接口一直到现在的200多个接口,不过对比SQLServer, Mysql还是OK的。其中最为核心的概念和方法差不多是2+6,

2个核心对象是:

  • The database connection object: sqlite3
  • The prepared statement object: sqlite3_stmt

6个最常用的方法是:

  • sqlite3_open()
  • sqlite3_prepare()
  • sqlite3_step()
  • sqlite3_column()
  • sqlite3_finalize()
  • sqlite3_close()

官网上很明确的指出sqlite3_exec和sqlite3_get_table都是对prepare/step的封装,务必理解prepare/step的运作方式,但在实际情况中,个人建议除了create以外都用prepare/step来解决,后面会说到原因。

还是从hello world开始,

continue reading...

Time in shell

No comments

.NET中我们通过Stopwatch来测试一个功能所耗费的时间,在Linux下当然也可以通过clock来得到begin和end,但是借助shell更加简便。

➜  ~  time sleep 3
sleep 3  0.00s user 0.00s system 0% cpu 3.004 total
➜  ~

一开始我还没看懂这句,解释一下,
[目标命令语句] [user时间] [system时间] [cpu占用率] [总时间]

user/system我个人理解为用户和内核,比如IO操作占用system远多过user,我们最关心的是整体时间也就是3.004,非常精确的数值。

参考内容:

在实践过程中你越多WPF你越会发现ViewModel是必不可少的,因为Model和View的匹配度事实上并不高,在写了N个ViewModel后来看看社区的框架学习一下,不过不看不知道,.NET Mvvm社区那个乱啊...有点失望。Anyway,有以下选择:

虽然Prism是官方选定的Mvvm,但问题是其文档冗长无比,好评度并不高,而MvvmLight则文档乏善可陈,最后根据devdigital周永恒的推荐下决定从CM开始。

来看Caliburn.Micro的hello world,
continue reading...

Part 1来看怎么extend generator。

首先切换到coffee-script,由于yo只认js,所以index.js中做过过渡,

require('coffee-script/register'); // cs1.7+
require('coffee-script');
module.exports = require('./index.coffee');

注: cs1.6 require('coffee-script'); cs1.7 require('coffee-script/register');

用coffee当然需要npm install coffee-script --save,这样才能require。然后index.coffee如下,

yeoman = require 'yeoman-generator'

class HelloGenerator extends yeoman.generators.Base
  constructor: (arg, options, config) ->
    yeoman.generators.Base.apply this, arguments
    this.config.save()

  hello: ->
    console.log 'hello coffee'

module.exports = HelloGenerator

然后yo试试。

continue reading...

之前的Walkthough yo中初步认识了一下yo,学着怎么去用yo快速建立项目,真的用起来才发现现有模板总是不合心意,所以自己建模板是早晚的事情。来看看如何来做一个generator。

官网的Writing Your Own Yeoman Generator | Yeoman这篇说得有点含糊,我自己实践下来步骤如下,

  1. mkdir generator-hello && cd $_,随便哪里都行,但目录必须是以generator-开始。
  2. npm init,初始化一个package.json
  3. package.json中name必须以generator-开头,同时keywords中一定包含yeoman-generator
    {
      "name": "generator-hello",
      "version": "0.1.0",
      "description": "",
      "keywords": ["yeoman-generator"]
    }
    
  4. npm install yeoman-generator --save,安装yeoman-generator,可以理解此package为generator的base class
  5. mkdir app && touch $_/index.js,然后通过tree验证
    ➜  generator-hello  tree -L 2
    .
    |-- app
    |   `-- index.js
    |-- node_modules
    |   `-- yeoman-generator
    `-- package.json
    
    3 directories, 2 files
    
  6. npm link,将此package挂到nom global中,通过nom ls -g --depth 0验证
  7. 至此已经完成了一半,输入yo以后已经能看到你的generator了
    ➜  generator-hello  yo
    [?] 'Allo nonocast! What would you like to do?
      Run the Express-coffee-app generator (0.1.0)
    ❯ Run the Hello generator (0.1.0)
      Run the Webapp generator (0.4.9)
      Run the Mocha generator (0.1.5)
      Update your generators
      Install a generator
      Find some help
      Get me out of here!
    
  8. continue reading...

.gitignore

1 comment

github/gitnogre集合了针对各种语言环境的.gitignore(忽略文件)模版,算是一个All in One的Pack。其中有2部分组成,根目录下的所有xxx.gitignore是针对项目,应该根据项目类型放在项目文件夹中,而Global则是针对操作系统,应该home目录下进行全局控制。

当然你可以根据你的情况进行定制比如,
Windows + VisualStudio + Node = windows.gitignore
Mac OSX + Node + Xcode + C = osx.gitignore

scp(secure copy - remote file copy program)在ssh基础上提供shell间cp,比ftp传输很多,属于必备技能,

scp <source> <target>

其中remote shell表示方法为user@address:file-path,比如nonocast@v.nonocast.cn:~表示指向nonocast的home,

实际操作如下图,

注解:其中-r针对目录。

Enjoy.

参考内容:

接着Part 1,这里介绍一下Upstart操作方式,首先安装Upstart, debian下直接apt-get install upstart,然后输入确认内容即可。

在/etc/init下编写配置文件,如hello.conf

description "hello service"
author "nonocast"

start on startup
stop on shutdown

respawn                # restart when job dies
respawn limit 5 60     # give up restart after 5 respawns in 60 seconds

script
  # Node needs HOME to be set
  export HOME="/home/www"
  chdir /home/www/gitd
  exec sudo -u www sh -c "/usr/local/bin/coffee /home/www/gitd/app.coffee >> /var/log/hello.log 2>&1"
end script

exec表示需要upstart控制的主程序,upstart会替我们很好的照顾exec启动的程序。

然后通过sudo start hello即可启动程序,同时还支持stop, restart, status,这里的start,stop命令都是initctl start,stop的link,提一下。
如果配置文件有问题,通过/var/log/upstart下的日志查看错误原因。
通过tail -f /var/log/hello.log即时查看node日志。
通过sudo initctl list可以查看upstart所有执行的服务。
同时,如果只是修改coffee内容,对应restart就可以重新加载,而如果修改了hello.conf,则需要sudo initctl reload hello更新upstart script。

关于upstart最后再补充一句,看上去upstart只是一个更好的init.d,事实上,更好的理解是upstart是一个系统级的hook,当收到系统的event时做出对应的响应,好比说插入U盘也能触发script,同时支持自定义Event,然后通过initctl emit触发,这个和node中event/emit异曲同工,而系统启动和系统关闭只是众多event其中的一种而已,所以不要曲解了upstart。

upstart中respawn虽然也能做到程序意外退出的重启,但始终还是不够的,就像StackOverflow上所说,

I highly recommend using both Monit AND upstart. Upstart makes it easy to deamonize node.js and Monit comes packed with tons of useful app checks including memory usage, http requests, cpu usage, ...

比如说程序虽然运行,但http请求无法响应,这种情况只能依靠Monit来做更复杂的判断,保证你的服务可持续性,同时他还可以在监测异常给出邮件、短信提示,让一切尽在掌握中。

debian下sudo apt-get install monit安装。安装完成后/etc/monit/monitrc是整个monit的配置文件,而/etc/monit/conf.d下放置针对你要监控的所有script,

vi /etc/monit/conf.d/hello.monitrc

check host hello with address 127.0.0.1
     start "/sbin/start hello"
     stop "/sbin/stop hello"
     if failed port 4000 protocol HTTP
          request /
          with timeout 5 seconds
          then restart

安装monit后,monit会自动生成一个init.d script,所以还需要sudo update-rc.d hello enable将monit加入启动,重启后通过monit status就可以查看服务状态了,如果手动关闭hello(sudo stop hello),monit status会看到应用offline,如下图,

再次刷新后,就自动还原为online,同时浏览器也可以继续访问网页,所以说Upstart+Monit就基本很好的照顾了Node,Enjoy it.

参考内容:


Powered by WordPress © 2014 nonocast   沪ICP备09095148号 Design by SRS Solutions