spread-client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.md +45 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/example/demo.rb +10 -0
- data/example/spread.conf +4 -0
- data/example/start.sh +1 -0
- data/lib/spread_client.rb +10 -0
- data/lib/spread_client/connection.rb +163 -0
- data/lib/spread_client/errors.rb +35 -0
- data/lib/spread_client/ffi.rb +41 -0
- data/lib/spread_client/messages.rb +22 -0
- data/spread-client.gemspec +62 -0
- data/test/helper.rb +7 -0
- data/test/test_connection.rb +51 -0
- data/test/test_connection_no_notify.rb +22 -0
- data/test/test_errors.rb +31 -0
- metadata +77 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Tim Lossen
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# spread_client
|
2
|
+
|
3
|
+
portable ruby bindings for the [spread toolkit](http://www.spread.org), version 3.17.x
|
4
|
+
|
5
|
+
## usage
|
6
|
+
|
7
|
+
sudo gem install spread-client -s http://gemcutter.org
|
8
|
+
|
9
|
+
then
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'spread_client'
|
13
|
+
|
14
|
+
c = SpreadClient::connect('bob')
|
15
|
+
c.join('chat')
|
16
|
+
c.multicast('chat', 'hello folks!')
|
17
|
+
c.leave('chat')
|
18
|
+
c.disconnect
|
19
|
+
|
20
|
+
## setup instructions
|
21
|
+
|
22
|
+
1. install the spread toolkit:
|
23
|
+
|
24
|
+
$ sudo port install spread
|
25
|
+
|
26
|
+
or
|
27
|
+
|
28
|
+
$ sudo apt-get install spread
|
29
|
+
|
30
|
+
or see <http://www.spread.org> for instructions on how to install from source.
|
31
|
+
|
32
|
+
2. create a simple `spread.conf`:
|
33
|
+
|
34
|
+
# one spread daemon running on port 4803 on localhost
|
35
|
+
Spread_Segment 127.0.0.255:4803 {
|
36
|
+
localhost 127.0.0.1
|
37
|
+
}
|
38
|
+
|
39
|
+
3. start the spread daemon:
|
40
|
+
|
41
|
+
$ spread -n localhost -c spread.conf
|
42
|
+
|
43
|
+
## Copyright
|
44
|
+
|
45
|
+
Copyright (c) 2009 Tim Lossen. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "spread-client"
|
8
|
+
gem.summary = "ruby bindings for libspread (built with ffi)"
|
9
|
+
gem.description = "portable ruby bindings for libspread (built with ffi)."
|
10
|
+
gem.email = "tim@lossen.de"
|
11
|
+
gem.homepage = "http://github.com/tlossen/spread_client"
|
12
|
+
gem.authors = ["Tim Lossen"]
|
13
|
+
gem.files.include('lib/**/*.rb')
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
require 'rake/rdoctask'
|
29
|
+
Rake::RDocTask.new do |rdoc|
|
30
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
31
|
+
|
32
|
+
rdoc.rdoc_dir = 'rdoc'
|
33
|
+
rdoc.title = "spread_client #{version}"
|
34
|
+
rdoc.rdoc_files.include('README*')
|
35
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
36
|
+
end
|
37
|
+
|
38
|
+
task :test => :check_dependencies
|
39
|
+
task :default => :test
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/example/demo.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'spread_client')
|
2
|
+
|
3
|
+
c = SpreadClient::connect('bob')
|
4
|
+
c.join('chat')
|
5
|
+
puts c.receive().inspect
|
6
|
+
c.multicast('chat', 'hello folks!')
|
7
|
+
puts c.receive().inspect
|
8
|
+
c.leave('chat')
|
9
|
+
puts c.receive().inspect
|
10
|
+
c.disconnect
|
data/example/spread.conf
ADDED
data/example/start.sh
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
spread -n localhost -c spread.conf
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ffi'
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), 'spread_client', 'ffi')
|
5
|
+
require File.join(File.dirname(__FILE__), 'spread_client', 'connection')
|
6
|
+
require File.join(File.dirname(__FILE__), 'spread_client', 'errors')
|
7
|
+
require File.join(File.dirname(__FILE__), 'spread_client', 'messages')
|
8
|
+
|
9
|
+
|
10
|
+
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module SpreadClient
|
2
|
+
|
3
|
+
class Connection
|
4
|
+
|
5
|
+
UNRELIABLE_MESS = 0x00000001
|
6
|
+
RELIABLE_MESS = 0x00000002
|
7
|
+
FIFO_MESS = 0x00000004
|
8
|
+
CAUSAL_MESS = 0x00000008
|
9
|
+
AGREED_MESS = 0x00000010
|
10
|
+
SAFE_MESS = 0x00000020
|
11
|
+
REGULAR_MESS = 0x0000003f
|
12
|
+
|
13
|
+
SELF_DISCARD = 0x00000040
|
14
|
+
DROP_RECV = 0x01000000
|
15
|
+
|
16
|
+
REG_MEMB_MESS = 0x00001000
|
17
|
+
TRANSITION_MESS = 0x00002000
|
18
|
+
CAUSED_BY_JOIN = 0x00000100
|
19
|
+
CAUSED_BY_LEAVE = 0x00000200
|
20
|
+
CAUSED_BY_DISCONNECT = 0x00000400
|
21
|
+
CAUSED_BY_NETWORK = 0x00000800
|
22
|
+
MEMBERSHIP_MESS = 0x00003f00
|
23
|
+
|
24
|
+
ENDIAN_RESERVED = 0x80000080
|
25
|
+
RESERVED = 0x003fc000
|
26
|
+
REJECT_MESS = 0x00400000
|
27
|
+
|
28
|
+
SERVICE_TYPE = {
|
29
|
+
:unreliable => UNRELIABLE_MESS,
|
30
|
+
:reliable => RELIABLE_MESS,
|
31
|
+
:fifo => FIFO_MESS,
|
32
|
+
:causal => CAUSAL_MESS,
|
33
|
+
:agreed => AGREED_MESS,
|
34
|
+
:safe => SAFE_MESS
|
35
|
+
}
|
36
|
+
|
37
|
+
DEFAULT_SERVER = 'localhost'
|
38
|
+
DEFAULT_PORT = 4803
|
39
|
+
DEFAULT_NOTIFY = true
|
40
|
+
DEFAULT_PRIORITY = 0
|
41
|
+
DEFAULT_SERVICE_TYPE = :safe
|
42
|
+
DEFAULT_SELF_DISCARD = false
|
43
|
+
DEFAULT_MESSAGE_TYPE = 0
|
44
|
+
|
45
|
+
MAX_GROUPS = 16
|
46
|
+
MAX_GROUP_LENGTH = 32
|
47
|
+
MAX_MESSAGE_LENGTH = 512
|
48
|
+
|
49
|
+
def initialize(name, options = {}) #:nodoc:
|
50
|
+
@mbox, @name = *connect(name, options)
|
51
|
+
end
|
52
|
+
|
53
|
+
# the private group name of this connection.
|
54
|
+
def name
|
55
|
+
@name
|
56
|
+
end
|
57
|
+
|
58
|
+
# disconnect from the spread server.
|
59
|
+
def disconnect
|
60
|
+
result = SpreadClient.SP_disconnect(@mbox)
|
61
|
+
raise SpreadClient.error_for(result) unless result == 0
|
62
|
+
end
|
63
|
+
|
64
|
+
# join the given group.
|
65
|
+
def join(group)
|
66
|
+
result = SpreadClient.SP_join(@mbox, group)
|
67
|
+
raise SpreadClient.error_for(result) unless result == 0
|
68
|
+
end
|
69
|
+
|
70
|
+
# leave the given group.
|
71
|
+
def leave(group)
|
72
|
+
result = SpreadClient.SP_leave(@mbox, group)
|
73
|
+
raise SpreadClient.error_for(result) unless result == 0
|
74
|
+
end
|
75
|
+
|
76
|
+
# send a message to a group.
|
77
|
+
#
|
78
|
+
# options:
|
79
|
+
# * :service_type -- can be one of
|
80
|
+
# * :unreliable
|
81
|
+
# * :reliable
|
82
|
+
# * :fifo
|
83
|
+
# * :causal
|
84
|
+
# * :agreed
|
85
|
+
# * :safe (default)
|
86
|
+
# * :self_discard -- set this to true if you do not want to receive your own message (default is false)
|
87
|
+
def multicast(group, message, options = {})
|
88
|
+
options = { :service_type => DEFAULT_SERVICE_TYPE, :self_discard => DEFAULT_SELF_DISCARD }.merge(options)
|
89
|
+
service_type = SERVICE_TYPE[options[:service_type]] | (options[:self_discard] ? SELF_DISCARD : 0)
|
90
|
+
result = SpreadClient.SP_multicast(@mbox, service_type, group, DEFAULT_MESSAGE_TYPE,
|
91
|
+
message.length, message)
|
92
|
+
raise SpreadClient.error_for(result) if result < 0
|
93
|
+
end
|
94
|
+
|
95
|
+
# receive the next message or notification.
|
96
|
+
#
|
97
|
+
# this method blocks until a message is available.
|
98
|
+
def receive
|
99
|
+
service_type = FFI::MemoryPointer.new(:int)
|
100
|
+
sender = FFI::MemoryPointer.new(:char, MAX_GROUP_LENGTH)
|
101
|
+
num_groups = FFI::MemoryPointer.new(:int)
|
102
|
+
groups = FFI::MemoryPointer.new(:char, MAX_GROUPS * MAX_GROUP_LENGTH)
|
103
|
+
message_type = FFI::MemoryPointer.new(:int)
|
104
|
+
endian_mismatch = FFI::MemoryPointer.new(:int)
|
105
|
+
message = FFI::MemoryPointer.new(:char, MAX_MESSAGE_LENGTH)
|
106
|
+
result = SpreadClient.SP_receive(@mbox, service_type, sender, MAX_GROUPS, num_groups, groups,
|
107
|
+
message_type, endian_mismatch, MAX_MESSAGE_LENGTH, message)
|
108
|
+
raise SpreadClient.error_for(result) if result < 0
|
109
|
+
service_type = service_type.read_int
|
110
|
+
sender = sender.read_string
|
111
|
+
num_groups = num_groups.read_int
|
112
|
+
groups = read_groups(groups, num_groups)
|
113
|
+
message = message.read_string
|
114
|
+
case
|
115
|
+
when regularMessage?(service_type)
|
116
|
+
Message.new(sender, message)
|
117
|
+
when membershipMessage?(service_type)
|
118
|
+
Notification.new(sender, groups, causedBy(service_type))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def regularMessage?(type)
|
125
|
+
(type & REGULAR_MESS > 0) && !(type & REJECT_MESS > 0)
|
126
|
+
end
|
127
|
+
|
128
|
+
def membershipMessage?(type)
|
129
|
+
(type & MEMBERSHIP_MESS > 0) && !(type & REJECT_MESS > 0)
|
130
|
+
end
|
131
|
+
|
132
|
+
def causedBy(type)
|
133
|
+
case
|
134
|
+
when type & CAUSED_BY_JOIN > 0 then :join
|
135
|
+
when type & CAUSED_BY_LEAVE > 0 && type & REG_MEMB_MESS == 0 then :self_leave
|
136
|
+
when type & CAUSED_BY_LEAVE > 0 then :leave
|
137
|
+
when type & CAUSED_BY_DISCONNECT > 0 then :disconnect
|
138
|
+
when type & CAUSED_BY_NETWORK > 0 then :network
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def connect(name, options = {})
|
143
|
+
options = { :server => DEFAULT_SERVER, :port => DEFAULT_PORT, :notify => DEFAULT_NOTIFY }.merge(options)
|
144
|
+
spread_server = "#{options[:port]}@#{options[:server]}"
|
145
|
+
notify = options[:notify] ? 1 : 0
|
146
|
+
mbox = FFI::MemoryPointer.new(:int)
|
147
|
+
private_group = FFI::MemoryPointer.new(:char, MAX_GROUP_LENGTH)
|
148
|
+
result = SpreadClient.SP_connect(spread_server, name, DEFAULT_PRIORITY, notify, mbox, private_group)
|
149
|
+
raise SpreadClient.error_for(result) unless result == 1
|
150
|
+
[mbox.read_int, private_group.read_string]
|
151
|
+
end
|
152
|
+
|
153
|
+
def read_groups(pointer, number)
|
154
|
+
groups = []
|
155
|
+
number.times do |i|
|
156
|
+
groups << pointer[i * MAX_GROUP_LENGTH].read_string
|
157
|
+
end
|
158
|
+
groups
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SpreadClient
|
2
|
+
|
3
|
+
class Error < ::RuntimeError; end
|
4
|
+
|
5
|
+
class IllegalSpread < Error; end
|
6
|
+
class CouldNotConnect < Error; end
|
7
|
+
class RejectQuota < Error; end
|
8
|
+
class RejectNoName < Error; end
|
9
|
+
class RejectIllegalName < Error; end
|
10
|
+
class RejectNotUnique < Error; end
|
11
|
+
class RejectVersion < Error; end
|
12
|
+
class ConnectionClosed < Error; end
|
13
|
+
class RejectAuth < Error; end
|
14
|
+
|
15
|
+
class IllegalSession < Error; end
|
16
|
+
class IllegalService < Error; end
|
17
|
+
class IllegalMessage < Error; end
|
18
|
+
class IllegalGroup < Error; end
|
19
|
+
class BufferTooShort < Error; end
|
20
|
+
class GroupsTooShort < Error; end
|
21
|
+
class MessageTooLong < Error; end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def self.error_for(code)
|
26
|
+
errors = [nil,
|
27
|
+
IllegalSpread, CouldNotConnect, RejectQuota, RejectNoName, RejectIllegalName,
|
28
|
+
RejectNotUnique, RejectVersion, ConnectionClosed, RejectAuth,
|
29
|
+
nil,
|
30
|
+
IllegalSession, IllegalService, IllegalMessage, IllegalGroup, BufferTooShort,
|
31
|
+
GroupsTooShort, MessageTooLong]
|
32
|
+
errors.at(code.abs) || Error
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SpreadClient
|
2
|
+
extend FFI::Library
|
3
|
+
ffi_lib "libspread"
|
4
|
+
|
5
|
+
# open a connection to the given spread server.
|
6
|
+
#
|
7
|
+
# options:
|
8
|
+
# * :server (default is 'localhost')
|
9
|
+
# * :port (default is 4803)
|
10
|
+
# * :notify -- set this to false if you do not want to receive any group
|
11
|
+
# membership notifications (default is true)
|
12
|
+
def self.connect(name, options = {})
|
13
|
+
Connection.new(name, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# int SP_connect(const char* spread name, const char* private name, int priority, int group_membership,
|
19
|
+
# mailbox* mbox, char* private group);
|
20
|
+
attach_function :SP_connect, [:string, :string, :int, :int, :pointer, :pointer], :int
|
21
|
+
|
22
|
+
# int SP_disconnect(mailbox mbox);
|
23
|
+
attach_function :SP_disconnect, [:int], :int
|
24
|
+
|
25
|
+
# int SP_join(mailbox mbox, const char* group);
|
26
|
+
attach_function :SP_join, [:int, :string], :int
|
27
|
+
|
28
|
+
# int SP_leave(mailbox mbox, const char* group);
|
29
|
+
attach_function :SP_leave, [:int, :string], :int
|
30
|
+
|
31
|
+
# int SP_multicast(mailbox mbox, service service_type, const char* group, int16 mess_type,
|
32
|
+
# int mess_len, const char* mess);
|
33
|
+
attach_function :SP_multicast, [:int, :int, :string, :int16, :int, :string], :int
|
34
|
+
|
35
|
+
# int SP_receive(mailbox mbox, service* service_type, char sender[MAX_GROUP_NAME], int max_groups,
|
36
|
+
# int* num groups, char groups[][MAX_GROUP_NAME], int16* mess_type, int* endian_mismatch,
|
37
|
+
# int max_mess_len, char* mess);
|
38
|
+
attach_function :SP_receive, [:int, :pointer, :pointer, :int, :pointer, :pointer, :pointer, :pointer,
|
39
|
+
:int, :pointer], :int
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SpreadClient
|
2
|
+
|
3
|
+
class Message
|
4
|
+
attr_reader :sender, :text
|
5
|
+
|
6
|
+
def initialize(sender, text) #:nodoc:
|
7
|
+
@sender = sender
|
8
|
+
@text = text
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Notification
|
13
|
+
attr_reader :group, :members, :cause
|
14
|
+
|
15
|
+
def initialize(group, members, cause) #:nodoc:
|
16
|
+
@group = group
|
17
|
+
@members = members
|
18
|
+
@cause = cause
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{spread-client}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Tim Lossen"]
|
12
|
+
s.date = %q{2009-12-11}
|
13
|
+
s.description = %q{portable ruby bindings for libspread (built with ffi).}
|
14
|
+
s.email = %q{tim@lossen.de}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.md",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"example/demo.rb",
|
27
|
+
"example/spread.conf",
|
28
|
+
"example/start.sh",
|
29
|
+
"lib/spread_client.rb",
|
30
|
+
"lib/spread_client/connection.rb",
|
31
|
+
"lib/spread_client/errors.rb",
|
32
|
+
"lib/spread_client/ffi.rb",
|
33
|
+
"lib/spread_client/messages.rb",
|
34
|
+
"spread-client.gemspec",
|
35
|
+
"test/helper.rb",
|
36
|
+
"test/test_connection.rb",
|
37
|
+
"test/test_connection_no_notify.rb",
|
38
|
+
"test/test_errors.rb"
|
39
|
+
]
|
40
|
+
s.homepage = %q{http://github.com/tlossen/spread_client}
|
41
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = %q{1.3.5}
|
44
|
+
s.summary = %q{ruby bindings for libspread (built with ffi)}
|
45
|
+
s.test_files = [
|
46
|
+
"test/helper.rb",
|
47
|
+
"test/test_connection.rb",
|
48
|
+
"test/test_connection_no_notify.rb",
|
49
|
+
"test/test_errors.rb"
|
50
|
+
]
|
51
|
+
|
52
|
+
if s.respond_to? :specification_version then
|
53
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
54
|
+
s.specification_version = 3
|
55
|
+
|
56
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
57
|
+
else
|
58
|
+
end
|
59
|
+
else
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestConnection < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@c = SpreadClient::connect('bob')
|
7
|
+
rescue
|
8
|
+
raise "this test expects a spread server running at localhost:4803"
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
@c.disconnect if @c
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_self_join_message
|
16
|
+
@c.join('chat')
|
17
|
+
message = @c.receive
|
18
|
+
assert_equal SpreadClient::Notification, message.class
|
19
|
+
assert_equal :join, message.cause
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_self_leave_message
|
23
|
+
@c.join('chat')
|
24
|
+
@c.receive
|
25
|
+
@c.leave('chat')
|
26
|
+
message = @c.receive
|
27
|
+
assert_equal SpreadClient::Notification, message.class
|
28
|
+
assert_equal :self_leave, message.cause
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_multicast
|
32
|
+
@c.join('chat')
|
33
|
+
@c.receive
|
34
|
+
@c.multicast('chat', 'hello folks!')
|
35
|
+
message = @c.receive
|
36
|
+
assert_equal SpreadClient::Message, message.class
|
37
|
+
assert_equal @c.name, message.sender
|
38
|
+
assert_equal 'hello folks!', message.text
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_multicast_with_self_discard
|
42
|
+
@c.join('chat')
|
43
|
+
@c.receive
|
44
|
+
@c.multicast('chat', 'one', :self_discard => true)
|
45
|
+
@c.multicast('chat', 'two')
|
46
|
+
message = @c.receive
|
47
|
+
assert_equal 'two', message.text
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestConnectionNoNotify < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@c = SpreadClient::connect('bob', :notify => false)
|
7
|
+
rescue
|
8
|
+
raise "this test expects a spread server running at localhost:4803"
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
@c.disconnect if @c
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_regular_message
|
16
|
+
@c.join('chat')
|
17
|
+
@c.multicast('chat', 'hello folks!')
|
18
|
+
message = @c.receive
|
19
|
+
assert_equal SpreadClient::Message, message.class
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/test/test_errors.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestErrors < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_error_for
|
6
|
+
assert_equal SpreadClient::IllegalSpread, SpreadClient.error_for(-1)
|
7
|
+
assert_equal SpreadClient::CouldNotConnect, SpreadClient.error_for(-2)
|
8
|
+
assert_equal SpreadClient::RejectQuota, SpreadClient.error_for(-3)
|
9
|
+
assert_equal SpreadClient::RejectNoName, SpreadClient.error_for(-4)
|
10
|
+
assert_equal SpreadClient::RejectIllegalName, SpreadClient.error_for(-5)
|
11
|
+
assert_equal SpreadClient::RejectNotUnique, SpreadClient.error_for(-6)
|
12
|
+
assert_equal SpreadClient::RejectVersion, SpreadClient.error_for(-7)
|
13
|
+
assert_equal SpreadClient::ConnectionClosed, SpreadClient.error_for(-8)
|
14
|
+
assert_equal SpreadClient::RejectAuth, SpreadClient.error_for(-9)
|
15
|
+
|
16
|
+
assert_equal SpreadClient::IllegalSession, SpreadClient.error_for(-11)
|
17
|
+
assert_equal SpreadClient::IllegalService, SpreadClient.error_for(-12)
|
18
|
+
assert_equal SpreadClient::IllegalMessage, SpreadClient.error_for(-13)
|
19
|
+
assert_equal SpreadClient::IllegalGroup, SpreadClient.error_for(-14)
|
20
|
+
assert_equal SpreadClient::BufferTooShort, SpreadClient.error_for(-15)
|
21
|
+
assert_equal SpreadClient::GroupsTooShort, SpreadClient.error_for(-16)
|
22
|
+
assert_equal SpreadClient::MessageTooLong, SpreadClient.error_for(-17)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_error_for_fallback
|
26
|
+
assert_equal SpreadClient::Error, SpreadClient.error_for(0)
|
27
|
+
assert_equal SpreadClient::Error, SpreadClient.error_for(-10)
|
28
|
+
assert_equal SpreadClient::Error, SpreadClient.error_for(-100)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spread-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tim Lossen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-11 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: portable ruby bindings for libspread (built with ffi).
|
17
|
+
email: tim@lossen.de
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.md
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- example/demo.rb
|
33
|
+
- example/spread.conf
|
34
|
+
- example/start.sh
|
35
|
+
- lib/spread_client.rb
|
36
|
+
- lib/spread_client/connection.rb
|
37
|
+
- lib/spread_client/errors.rb
|
38
|
+
- lib/spread_client/ffi.rb
|
39
|
+
- lib/spread_client/messages.rb
|
40
|
+
- spread-client.gemspec
|
41
|
+
- test/helper.rb
|
42
|
+
- test/test_connection.rb
|
43
|
+
- test/test_connection_no_notify.rb
|
44
|
+
- test/test_errors.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/tlossen/spread_client
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options:
|
51
|
+
- --charset=UTF-8
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.5
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: ruby bindings for libspread (built with ffi)
|
73
|
+
test_files:
|
74
|
+
- test/helper.rb
|
75
|
+
- test/test_connection.rb
|
76
|
+
- test/test_connection_no_notify.rb
|
77
|
+
- test/test_errors.rb
|