Class: Rakie::Websocket

Inherits:
Object
  • Object
show all
Defined in:
lib/rakie/websocket.rb

Direct Known Subclasses

WebsocketServer

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(delegate = nil, channel = nil) ⇒ Websocket



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/rakie/websocket.rb', line 7

def initialize(delegate=nil, channel=nil)
  @delegate = delegate

  if channel == nil
    channel = TCPChannel.new('127.0.0.1', 10086, self)        
  end

  @channel = channel

  # @type [WebsocketMessage]
  @recv_message = WebsocketMessage.new

  # @type [Array<WebsocketMessage>]
  @send_messages = []
  @client_side = true
end

Instance Attribute Details

#channelObject (readonly)

Returns the value of attribute channel.



4
5
6
# File 'lib/rakie/websocket.rb', line 4

def channel
  @channel
end

#client_sideObject

Returns the value of attribute client_side.



3
4
5
# File 'lib/rakie/websocket.rb', line 3

def client_side
  @client_side
end

#delegateObject

Returns the value of attribute delegate.



3
4
5
# File 'lib/rakie/websocket.rb', line 3

def delegate
  @delegate
end

Instance Method Details

#closeObject



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/rakie/websocket.rb', line 139

def close
  ws_message = WebsocketMessage.new
  ws_message.fin = true
  ws_message.op_code = WebsocketMessage::OP_CLOSE

  if @client_side
    ws_message.mask = true
    ws_message.refresh_masking
  end

  ws_message.payload = "close"

  send_message = ws_message.to_s

  Log.debug("Rakie::Websocket send close: #{send_message}")

  @channel.write(send_message) # Response data
end

#on_close(channel) ⇒ Object



110
111
112
113
114
# File 'lib/rakie/websocket.rb', line 110

def on_close(channel)
  if @delegate
    @delegate.on_disconnect(self)
  end
end

#on_recv(channel, data) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rakie/websocket.rb', line 25

def on_recv(channel, data)
  Log.debug("Rakie::Websocket recv len: #{data.length}")

  total_parsed = 0

  while data.length > 0
    # @type [WebsocketMessage] request
    message = @recv_message

    if message.parse_status == ParseStatus::COMPLETE
      message = WebsocketMessage.new
      @recv_message = message
    end

    len = message.parse(data)
    total_parsed += len

    Log.debug("Rakie::Websocket receive message: #{message.payload} parse with #{len}")

    if message.parse_status == ParseStatus::COMPLETE
      response = WebsocketMessage.new

      if message.op_code == WebsocketMessage::OP_PING
        response.fin = true
        response.op_code = WebsocketMessage::OP_PONG
        response.payload = "Rakie::Websocket: op pong"

      elsif message.op_code == WebsocketMessage::OP_PONG
        response.fin = true
        response.op_code = WebsocketMessage::OP_PING
        response.payload = "Rakie::Websocket: op ping"

      elsif message.op_code == WebsocketMessage::OP_CLOSE
        channel.close

        Log.debug("Rakie::Websocket: op close")
        return 0

      elsif @delegate
        @delegate.on_message(self, message.payload)

      else
        response.fin = true
        response.op_code = WebsocketMessage::OP_TEXT
        response.payload = "Rakie!"
      end
      
      # response_data = response.to_s

      # Log.debug("Rakie::Websocket response: #{response_data}")

      # channel.write(response_data) # Response data

    elsif message.parse_status == ParseStatus::CONTINUE
      break

    elsif message.parse_status == ParseStatus::ERROR
      channel.close

      Log.debug("Rakie::Websocket: Illegal message")
      return 0
    end

    if len >= data.length
      break
    end

    data = data[len .. -1]
  end

  return total_parsed
end

#on_send(channel) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rakie/websocket.rb', line 98

def on_send(channel)
  # @type [WebsocketMessage]
  last_message = @send_messages.shift

  if last_message
    if last_message.op_code == WebsocketMessage::OP_CLOSE
      Log.debug("Rakie::Websocket: send finish and close channel")
      channel.close
    end
  end
end

#send(message, is_binary = false) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/rakie/websocket.rb', line 116

def send(message, is_binary=false)
  ws_message = WebsocketMessage.new
  ws_message.fin = true
  ws_message.op_code = WebsocketMessage::OP_TEXT
  ws_message.payload = message

  if is_binary
    ws_message.op_code = WebsocketMessage::OP_BIN
  end

  if @client_side
    ws_message.mask = true
    ws_message.refresh_masking
  end

  send_message = ws_message.to_s
  @send_messages << ws_message

  Log.debug("Rakie::Websocket send: #{send_message} with #{send_message.length}")

  @channel.write(send_message) # Response data
end