JCSP を使って書いたチャットのコード(1)

某氏(ここの人)に薦められて CSP 調べ中^^;。

JCSPhttp://www.cs.kent.ac.uk/projects/ofa/jcsp/ から持ってこれる CSP の Java 実装。

はっきりいってまだ用語関連がよく分かってないけど^^;、CSP(Communicationg Sequential Process) は並列/分散の分野では有名で、プロセス代数に基づいており、形式的にプログラムを記述可能である、というのが特徴。

CSP の実装としては occam という言語があり、この言語でできることを Java(やC)でも、ということで作られたのが JCSP。

上記URLからフリーでダウンロードできる JCSP 実装はネットワーク非対応なので以下のチャットは単にローカルマシン上に4枚のウインドウを開くだけのものですが、ネットワーク対応版のライブラリに差し替えれば Channel 取得部分を変更するだけで P2P タイプのチャットができるようになります。

今回のは jcsp.awt を用いない版。


[Chat.java]
import java.awt.*;
import java.awt.event.*;
import jcsp.lang.*;
import jcsp.util.*;
import jcsp.plugNplay.*;

class Chat {
public static void main(String[] args) throws Exception {
Any2OneChannel sendSocket =
Any2OneChannel.create(new OverWriteOldestBuffer(10));

CSProcess[] nodes = new CSProcess[5];
Channel[] readSockets =
One2OneChannel.create(
nodes.length - 1,
new OverWriteOldestBuffer(10));

for (int i = 0; i < nodes.length - 1; i++) {
nodes[i] = new ChatWindow("node:" + i, readSockets[i], sendSocket);
}
// broadcast filter process
nodes[nodes.length - 1] = new Delta(sendSocket, readSockets);

new Parallel(nodes).run();
}
}

class ChatWindow implements CSProcess {
private String name;
private ChannelInput in;
private ChannelOutput out;

Frame frame;
TextArea view;
TextField input;

public ChatWindow(String name, ChannelInput in, ChannelOutput out) {
this.name = name;
this.in = in;
this.out = out;

frame = new Frame("Example");

view = new TextArea("", 20, 60);
view.setEditable(false);
input = new TextField();
input.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
if (input.getText().length() == 0) return;
ChatWindow.this.out.write(input.getText());
input.setText("");
}
});

Panel p = new Panel(new BorderLayout());
p.add(view, BorderLayout.CENTER);
p.add(input, BorderLayout.SOUTH);

frame.setBackground(Color.green);
frame.add(p);
frame.pack();
input.requestFocus();
}

public void run() {
frame.setVisible(true);
while (true) {
String s = (String)in.read();
view.append(s);
view.append("\n");
}
}
}