Back

socket - websocket 0 基础入门,和搭建websocket server的简单而快速的办法 (linux下)

发布时间: 2017-11-21 00:32:00

注意:  这个系列文章非常好:  https://www.rails365.net/articles/websocket-xu-lie-wen-zhang-mu-lu 可以作为 0 基础的同学的入门

websocket 是基于web的类似于socket协议的一种东东。 不过 websocket 与 socket的关系,就好像javascript 与 java的关系, 巴基斯坦与卡巴斯基的关系,张三与张三丰的关系。。。 Orz 有基巴关系。。。

windows 下的失败原因: windows下出现各种诡异问题,无法解决。 例如: 无法运行.bat, .cmd脚本,无法直接运行ruby命令。 github issues页面也没有给出解释。

http的特点: 

1. 单方面请求。 (浏览器 ->  服务器)

2. 无法保存状态

socket特点:

1. 双方向请求。 

2. 有状态。

websocket 也分成 80端口(ws://) 和 433端口(wss://) 

可以使用这个server 来实现任何后端语言: https://github.com/joewalnes/websocketd

1. 先在本机安装个 websocket server:  见上图github. 下来下来就是个二进制文件。

2. 使用一个 sh 脚本。  如下:

$ chmod +x test_echo.sh
$ ./test_echo.sh
1
2
3
4
5
6
7
8
9
10

3. 使用 websocketd 来运行( 务必记得 对应的脚本是有权限的)

websocketd --port=3333 ./test_echo.sh

4. 打开一个html文件,内容如下:

<html>
  <pre id="log"></pre>
  <script>
function log(msg){
  document.getElementById('log').textContent += msg + '\n';
}

var ws = new WebSocket('ws://localhost:3333');

ws.onopen = function(){
  log('connect')
}

ws.onclose = function(){
  log('close')
}

ws.onmessage = function(event){
  log('message: ' + event.data)
}

  </script>
</html>

可以看出, 客户端的几个关键方法:   

onopen,   打开时调用

onclose,   关闭时调用

onmessage, 收到消息时调用

Rails 4.2 中使用websocket

需要跟 tubesock, redis , rails 一起使用。参考:  https://www.rails365.net/articles/websocket-zhi-yong-tubesock-zai-rails-shi-xian-liao-tian-shi-wu

1. 新建一个action:   /welcome/chat  , 这个action 就是专门复杂处理socket 请求的。可以认为这个action就承担着  websocket服务器的职能。 它的访问链接是:  ws://localhost:3000/welcome/chat 

代码如下:

#Gemfile:  (版本号随意)

gem 'tubesock'
gem 'puma', '3.11.0'
gem 'redis-rails', '5.0.2'

# routes.rb
  get '/welcome/chat' => 'welcome#chat'
  get '/welcome/test_chat' => 'welcome#test_chat'

# welcome_controller.rb: 
  include Tubesock::Hijack
  def chat
    hijack do |tubesock|
      redis_thread = Thread.new do
        Redis.new.subscribe "chat" do |on|
          on.message do |channel, message|
            tubesock.send_data message
          end 
        end 
      end 

      tubesock.onmessage do |m| 
        Redis.new.publish "chat", m
      end 

      tubesock.onclose do
        redis_thread.kill
      end 
    end
  end

# config/application.rb 中,增加:
config.cache_store = :redis_store, "redis://localhost:6379/2/cache", { expires_in: 90.minutes }
否则会报错。 报莫名其妙的错误。 (不看full stack trace 看不出来。 看了之后也只能大体猜到是redis的问题, 没配置好。)

2. 记得,在上一步的时候, redis 要启动 (telnet localhost 6379) 

3. 然后,我们就可以在 web browser的console中,测试一下: 

socket = new WebSocket("ws://localhost:3000/welcome/chat")
WebSocket {url: "ws://localhost:3000/welcome/chat", readyState: 0, bufferedAmount: 0, onopen: null, onerror: null, …}

4. 我们接下来,就可以单独写一个页面了。 (注意要新增一个erb页面: test_chat )

<h1>Tubesock Chat</h1>
<pre id="output"></pre>
<form class="chat">
  <input placeholder="hello world" autofocus>
</form>
<script src="http://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script>

<script>
jQuery(function(){
  socket = new WebSocket("ws://localhost:3000/welcome/chat")

  socket.onmessage = function(event) {
    if(event.data.length){
      $("#output").append(event.data + "<br />")
    }
  }

  $("body").on("submit", "form.chat", function(event){
    event.preventDefault()
    $input = $(this).find("input")
    socket.send($input.val())
    $input.val(null)
  })
})
</script>
            

在Rails中增加websocket,  需要注意的是:

1.  一旦controller创建好之后(controller, Gemfile ) ,如果页面没有实际内容的操作代码, 页面会一直转圈,但是不会显示任何内容。等一会儿就会报错。

实际上,我们看下后台,会发现,后台的日志中, 有 

17:00:50 INFO: Completed -1 in 64ms (Views: 1.0ms | ActiveRecord: 9.5ms)

这个就说明成了。

Back