Unityでソケットサーバーを建てる

はじめに

ソケットサーバー作るよ!
Unityでソケット通信したい!って思って調べたらあんまり情報が見つからなかったので泣いた
のでメモ

バージョン

  • Unity 5.3

コード

幾つかポート開けて見たかったので適当に継承して使うクラスを作ってみた
C#良く分からんので指摘があったら是非
try-catch今書いたからおかしいかもしれない

SocketServer.cs

 1using UnityEngine;
 2using System;
 3using System.IO;
 4using System.Net;
 5using System.Net.Sockets;
 6using System.Collections.Generic;
 7
 8public class SocketServer : MonoBehaviour {
 9    TcpListener listener = null;
10    List<TcpClient> clients = new List<TcpClient>();
11    readonly object lockObj = new object();
12
13    protected void listen(string host, int port){
14        IPAddress ip = IPAddress.Parse(host);
15        listener = new TcpListener(ip, port);
16        listener.Start();
17        listener.BeginAcceptSocket(OnRequested, listener);
18    }
19
20    public void sendMessage(string msg){
21        if (clients.Count == 0){
22            return;
23        }
24        byte[] body = System.Text.Encoding.UTF8.GetBytes(msg);
25
26        foreach(var client in clients){
27            try{
28                    NetworkStream stream = client.GetStream();
29                    stream.Write(body, 0, body.Length);
30            }catch (Exception e){
31                    clients.Remove(client);
32            }
33        }
34    }
35
36    protected virtual void OnApplicationQuit() {
37        if (listener == null){
38            return;
39        }
40
41        if (clients.Count != 0){
42            foreach(var client in clients){
43                client.Close();
44            }
45        }
46
47        listener.Stop();
48
49	}
50
51    protected virtual void OnMessage(string msg){
52        // Debug.Log(msg);
53    }
54
55    void OnRequested(IAsyncResult ar) {
56		lock (lockObj) {
57			TcpListener listener = (TcpListener)ar.AsyncState;
58			TcpClient client = listener.EndAcceptTcpClient(ar);
59            clients.Add(client);
60			NetworkStream stream = client.GetStream();
61
62			StreamReader reader = new StreamReader(stream);
63
64			while (client.Connected) {
65				while (!reader.EndOfStream){
66					OnMessage(reader.ReadLine());
67				}
68
69				if (client.Client.Poll(1000, SelectMode.SelectRead) && (client.Client.Available == 0)) {
70					clients.Remove(client);
71					break;
72				}
73			}
74			listener.BeginAcceptSocket(OnRequested, listener);
75		}
76	}
77}

使い方

これを継承したクラスを作る

Server.cs

 1public class Server : SocketServer {
 2    public string host = "127.0.0.1";
 3    public int port = 9090;
 4
 5    void start(){
 6        base.listen(host, port);
 7    }
 8
 9    protected override void OnMessage(string msg){
10        Debug.Log(msg);
11        sendMessage(msg);
12    }
13}

みたいな感じで使える