Class: Iarm::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/iarm/server.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.start(uri = nil) ⇒ Object



127
128
129
130
# File 'lib/iarm/server.rb', line 127

def self.start(uri=nil)
  DRb.start_service(uri, self.new)
  DRb.thread
end

Instance Method Details

#depart(who, channel = nil) ⇒ Object

nil=depart ALL channels and log out client



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/iarm/server.rb', line 51

def depart(who, channel=nil)  # nil=depart ALL channels and log out client
  @mutex.synchronize do
    (channel.nil? ? @channels_joined[who] : [ channel ]).each do |ch|
      @channels_joined[who].delete(ch)
      if @channel_members[ch].delete(who)
        send_msg(Msg::Part.new(ch, who))
      end
      check_channel_empty(ch)
    end
    kill_client(who) if(channel.nil?)
  end
  
end

#get_topic(channel) ⇒ Object



119
120
121
# File 'lib/iarm/server.rb', line 119

def get_topic(channel)
  @topics[channel]
end

#getmsg(who, timeout = 0) ⇒ Object

returns msg or nil if no messages and timed out. also serves as a keep-alive to avoid getting killed by ttl if who=nil then it listens on all channels, but only one client can do this at once if another client is already listening with the same who-id, it has the effect of making them return immediately (before their timeout is up)



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/iarm/server.rb', line 70

def getmsg(who, timeout=0)
  if(@msgs[who].empty? && timeout != 0)
    wait_existing = false
    msg = @mutex.synchronize do
      wait_existing = Iarm::Timer.poke(@listeners[who])
      next_msg(who)
    end
    return msg if(msg)
    
    if(wait_existing)
      Thread.pass while(@mutex.synchronize { @listeners.has_key?(who) })
    end

    #puts "Timer.wait: timeout=#{timeout}"
    Iarm::Timer.wait(timeout) do |mode|
      @mutex.synchronize do
        mode ? @listeners[who] = Thread.current : @listeners.delete(who)
      end
      #puts "IARM getmsg: #{who} #{mode ? 'entering' : 'exiting'} wait with msgcount=#{@msgs[who].length}"
      Iarm::Timer.poke(Thread.current) if mode && @msgs[who].length>0  # don't bother sleeping if we already have a new message waiting
    end
  end
  @mutex.synchronize { next_msg(who) }
end

#getmsgs(who, timeout = 0) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/iarm/server.rb', line 95

def getmsgs(who, timeout=0)
  res = [ getmsg(who, timeout) ]
  while(!res.empty? && (msg = getmsg(who, 0)))
    res << msg
  end
  res
end

#join(who, channel, key = nil) ⇒ Object

returns true if joined, false if denied, and nil if new channel formed



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/iarm/server.rb', line 29

def join(who, channel, key=nil)      # returns true if joined, false if denied, and nil if new channel formed
  retval = nil
  touch_nickname(who)
  @mutex.synchronize do
    if(@channels.has_key?(channel))
      retval = (@channels[channel] == key) 
    else
      @channels[channel] = key
    end

    if(retval != false)  # if retval is true (joined existing) or nil (new channel formed)
      if(!@channel_members[channel].has_key?(who)) # don't re-join them if they've already joined before
        @channel_members[channel][who] = clockval
        @channels_joined[who] << channel
        send_msg(Msg::Join.new(channel, who, @channel_members[channel][who]))
        post_msg(who, @topics[channel]) if @topics.has_key?(channel)
      end
    end
  end
  retval
end

#list(pattern = nil) ⇒ Object



17
18
19
# File 'lib/iarm/server.rb', line 17

def list(pattern=nil)
  pattern ? @channels.keys.grep(pattern) : @channels.keys
end

#pingObject



10
11
12
# File 'lib/iarm/server.rb', line 10

def ping
  'pong'
end

#post(msg) ⇒ Object



123
124
125
# File 'lib/iarm/server.rb', line 123

def post(msg)
  @mutex.synchronize { send_msg(msg) } if(msg.kind_of?(Msg))
end

#say(who, channel, data) ⇒ Object



103
104
105
# File 'lib/iarm/server.rb', line 103

def say(who, channel, data)
  post(Iarm::Msg.new(channel, who, data))
end

#set_topic(who, channel, data) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/iarm/server.rb', line 107

def set_topic(who, channel, data)
  touch_nickname(who)
  if @channels.has_key?(channel)
    data = Msg::Topic.new(channel, who, data) unless data.kind_of?(Msg::Topic)
    if(@topics[channel] != data)
      @mutex.synchronize { @topics[channel] = data }
      post(data)
      data
    end
  end
end

#ttl(ttl_secs) ⇒ Object



13
14
15
# File 'lib/iarm/server.rb', line 13

def ttl(ttl_secs)
  @ttl_secs = ttl_secs
end

#who(channel) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/iarm/server.rb', line 21

def who(channel)
  if(@channels.has_key?(channel))
    @channel_members[channel] #.each {|w,time| post_msg(who, Msg::ChannelMember.new(channel, w, time)) } 
  else
    {}
  end
end