Created
February 21, 2012 21:46
-
-
Save johnkchow/1879194 to your computer and use it in GitHub Desktop.
Simple EventMachine TCP messaging framing example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'bindata' | |
module ServerConnection | |
def receive_data(data) | |
@buffer ||= [] | |
@data_size ||= 0 | |
@current_size ||= 0 | |
if @buffer.empty? | |
# First four characters of any framed message will always be the size of message | |
@data_size = BinData::Uint32be.read(@buffer[0..3]).to_i | |
data = data[4..-1] | |
end | |
take_data_size = @data_size - @current_size | |
fragment = data[0..take_data_size] | |
@buffer << fragment | |
@current_size += fragment.length | |
if @current_size == @data_size | |
begin | |
process_message(@buffer.join) | |
rescue => e | |
# make sure you catch your exceptions here or your server will explode! | |
ensure | |
# if you're catching exceptions, make sure you always clear your buffer in the end | |
# otherwise it'll mess with your next framed messaging processing | |
@buffer.clear | |
@current_size = 0 | |
@data_size = 0 | |
# In the case where we received the next framed message, | |
# recursively call receive_data to process it | |
receive_data(data[(take_data_size + 1)..-1]) if data.length > take_data_size | |
end | |
end | |
end | |
def send_message(message) | |
# Will always be four characters long | |
length = BinData::Uint32be.new(message.length).to_binary_s | |
send_data(length+message) | |
end | |
def process_message(message) | |
# do something here to process it | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
module ServerConnection
def receive_data(data)
@buffer ||= []
@data_size ||= 0
@current_size ||= 0
end
def send_message(message)
# Will always be four characters long
length = BinData::Uint32be.new(message.length).to_binary_s
end
def process_message(message)
# do something here to process it
end
end