さくらレンタルサーバでPython Twistedによるチャットサーバを動かす


***** ご注意 *****

さくらレンタルサーバ内での常駐プロセスの起動は、さくらレンタルサーバの禁止事項で禁止されています。
本記事のプログラムを試される方は、Twistedサーバプログラムの起動は、一時的にして頂きますようお願い致します。

さくらレンタルサーバSSHでリモートログインし、以下の手順に従って、Python Twistedをインストール:

> bash
> mkdir ~/tmp
> cd ~/tmp
> wget http://twistedmatrix.com/Releases/Twisted/12.0/Twisted-12.0.0.tar.bz2
> tar xvfz Twisted-12.0.0.tar.bz2
> cd Twisted-12.0.0.tar.bz2
> mkdir -p ~/lib/python2.7/site-packages/
> export PYTHONPATH=~/lib/python2.7/site-packages/
> python setup.py install --prefix=~
> echo export PYTHONPATH=~/lib/python2.7/site-packages/ >> ~/.bashrc 

最後の一行がないと、次回ログインした際に、Twistedパッケージが見えなくなってしまう。
以下により、無事にインストールできたか確認:

> python
>> import twisted
>> exit()

これだけでは面白くないので、簡単なTCPサーバを構築してみる。
How To Create A Socket Based iPhone App and Serverを参考に、TCPで動作するチャットサーバを動かしてみる。
この上記チュートリアルiPhoneアプリとセットになっているが、チャットサーバだけでも試せる。
チュートリアルを基に、server.pyという名前で以下のPythonコードを記述:

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor


class IphoneChat(Protocol):
	def connectionMade(self):
		#self.transport.write("""connected""")
		self.factory.clients.append(self)
		print "clients are ", self.factory.clients
	
	def connectionLost(self, reason):
	    self.factory.clients.remove(self)
	
	def dataReceived(self, data):
	    #print "data is ", data
		data = data.strip()
		a = data.split(':')
		if len(a) > 1:
			command = a[0]
			content = a[1]
			
			msg = ""
			if command == "iam":
				self.name = content
				msg = self.name + " has joined"
				
			elif command == "msg":
				msg = self.name + ": " + content
			
			print msg
						
			for c in self.factory.clients:
				c.message(msg)
				
	def message(self, message):
		self.transport.write(message + '\n')


factory = Factory()
factory.protocol = IphoneChat
factory.clients = []

reactor.listenTCP(8080, factory)
print "Iphone Chat server started"
reactor.run()

ここで、リッスンポートを80から8080に変更している事に注意。
実装後、以下のコマンドにより、チャットサーバを起動:

> python server.py
Iphone Chat server started

ローカル端末でコンソールを2つ開き、それぞれからtelnetTCPサーバに接続:

> telnet <TCPサーバURL> 8080
Trying <TCPサーバIPアドレス>...
Connected to <TCPサーバURL>.
Escape character is '^]'.

それぞれのコンソール(コンソールA/コンソールB)からチャットコマンドを送信すると、TCPサーバを介してチャットが出来る:
・コンソールA

telnet <TCPサーバURL> 8080
Trying <TCPサーバIPアドレス>...
Connected to <TCPサーバURL>.
Escape character is '^]'.
iam:Mike                 # (1)
Mike has joined       # (2)
Sam has joined        # (4)
Sam: Hi, Mike!         # (6)
msg: Hello, Sam!!    # (7)
Mike:  Hello, Sam!!  # (8)

・コンソールB

telnet <TCPサーバURL> 8080
Trying <TCPサーバIPアドレス>...
Connected to <TCPサーバURL>.
Escape character is '^]'.
Mike has joined       # (2)
iam:Sam                  # (3)
Sam has joined        # (4)
msg:Hi, Mike!          # (5)
Sam: Hi, Mike!         # (6)
Mike:  Hello, Sam!!  # (8)

各コンソール中のコメントの数字は、入出力の順番。それぞれTCPサーバに参加し、互いにメッセージをやり取りできていることが確認できる。