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

Returns a new instance of Websocket.

Parameters:



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

Parameters:

  • data (String)


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