Websocket, http.send: "undefined method `asdfg'"

Hello everyone,

I just started to learn Ruby. As a learning-by-doing project I chose
something with websockets. Maybe a bit ambitious, as I only did some
Perl many years ago and had C beginners courses in university…
Anyway, I can be quite stubborn!

I successfully connect to a websocket server and can receive its output.
However, trying to send it strings (for the handshake) fails.

Stripped-down source:

##################

EventMachine.run {
http = EventMachine::HttpRequest.new(“ws://websocketstest.com”).get
:timeout => 0

http.errback { puts “oops” }
http.callback {
puts “WebSocket connected!”

http.send("asdfg")

}

##################

Output:
websocket.rb:16:in send': undefined methodasdfg’ for
#EventMachine::HttpClient:0x7f8fb3cc4490 (NoMethodError)

##################

This code is posted in several places as an example for using
websockets.
Included ruby gems: ‘rubygems’ ‘eventmachine’ ‘em-http-request’
‘em-http’
“http.send” seems to be recognized and called, I am totally lost why it
doesnt transfer the string “asdfg” to “http.send”.

I am grateful for any hints. Also if etiquette would suggest me to post
or format differently.

Thank you,

Manuel

http.send("asdfg")

}

##################

Output:
websocket.rb:16:in send': undefined method asdfg’ for
#EventMachine::HttpClient:0x7f8fb3cc4490 (NoMethodError)

send is a method that is used to dynamically call a method given a
symbol or string:

http://ruby-doc.org/core/classes/Object.html#M000999

This is why it’s trying to call a method. I believe you want something
like write instead.

Regards,
Chris W.
http://www.twitter.com/cwgem

Thank you for your reply, Chris.
I looked more into ‘send’, ‘write’, ‘print’ and more. They work as
intended (I can send a string to a http connection) when I open a
connection with TCPSocket. No chance when trying it inside the posted
EventMachine. By now I suspect it has nothing to do with websockets at
all, but is something like “missing methods” in EventMachine? I found
more online examples which are identical to my code. Maybe something is
wrong with my (out of the box) Debian Ruby setup.
After reading and trying for two days now, I consider to give up and go
back to Perl, or to leave it altogether.

frustrated,

Manuel

Edit:

Working example from http://www.rubycentral.com/pickaxe/tut_io.html:

require ‘socket’
client = TCPSocket.open(‘localhost’, ‘finger’)
client.send(“oracle\n”, 0) # 0 means standard packet
puts client.readlines
client.close

Almost identical code inside EventMachine doesnt work:

require ‘rubygems’ ‘eventmachine’ ‘em-http-request’

EventMachine.run {
client = EventMachine::HttpRequest.new(“ws://websocketstest.com”).get
:timeout => 0
client.errback { puts “oops” }
client.callback {
puts “WebSocket connected!”
client.send(“GET /index.html HTTP/1.1\n”, 0)
}
}

test.rb:17:in send': undefined method GET /index.html HTTP/1.1
(NoMethodError)

Manuel M. wrote in post #1024484:

I looked more into ‘send’, ‘write’, ‘print’ and more. They work as
intended (I can send a string to a http connection) when I open a
connection with TCPSocket.

TCPSocket has its own ‘send’ method, which overrides Object#send and
does something different (write data, not invoke a method)

No chance when trying it inside the posted
EventMachine.

So use ‘write’ instead of ‘send’, as was suggested.

test.rb:17:in send': undefined methodGET /index.html HTTP/1.1
(NoMethodError)

Correct. The same is true of any object:

irb(main):001:0> myobject = “hello”
=> “hello”
irb(main):002:0> myobject.send(“GET /index.html HTTP/1.1”)
NoMethodError: undefined method GET /index.html HTTP/1.1' for "hello":String from (irb):2:insend’
from (irb):2
from :0

  • except for the few classes which (perhaps confusingly) override
    Object#send to do something else.