Периодически возвращаюсь к этому вопросу и вот сейчас уже совсем плотно. Есть сервер, который слушает порт по UDP протоколу и отвечает клиент в зависимости от прилетевшей команды. Код сервера до нельзя прост:
Код
public static void Main() { int recv; DB = new UserBD(); byte[] data = new byte[1024]; LogService LOG = new LogService(); LogService.MessConstcructor Message = new LogService.MessConstcructor(); string[] InputParams; Console.WriteLine("Для продолжения нажмите Enter."); Console.ReadLine(); Socket mysocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 23000); mysocket.Bind(ipep); IPEndPoint sender = new IPEndPoint(IPAddress.Any, 23001); EndPoint Remote = (EndPoint)sender; Message.DateTime = DateTime.Now.ToString(); Message.UserName = "System"; Message.MessType = "System"; Message.Message = "Запуск сервера"; LOG.AddString(Message); Message.Message = "Попытка подключения к базам данных"; LOG.AddString(Message); if (!DB.DBConnect()) { Message.MessType = "Error"; Message.Message = "Ошибка подключения к базе MySQL"; LOG.AddString(Message); } else { try { Message.MessType = "Event"; Message.Message = "Успешное подключение к базам. Запуск сокета"; LOG.AddString(Message); while (true) { recv = mysocket.ReceiveFrom(data, ref Remote); if (recv == 0) break; string message = Encoding.ASCII.GetString(data, 0, recv); InputParams = message.Split('|'); string UserID; switch (InputParams[0]) { case "Auth": //попытка авторизации UserID = Auth(InputParams[1], InputParams[2]); if (UserID!=null) { Message.UserName = InputParams[1]; Message.MessType = "Event"; Message.Message = "Успешая авторизация"; LOG.AddString(Message); data = Encoding.ASCII.GetBytes("Success|" + UserID); } else { Message.UserName = InputParams[1]; Message.MessType = "Error"; Message.Message = "Ошибка авторизации пользователя"; LOG.AddString(Message); data = Encoding.ASCII.GetBytes("Failure"); } break; case "getWeaponsList": Message.UserName = InputParams[1]; Message.MessType = "Event"; Message.Message = "Запрос списка Оружия"; LOG.AddString(Message); string result = DB.getWeaponsList(); data = Encoding.ASCII.GetBytes("Success|" + result); break; case "Test": Message.UserName = "Test"; Message.MessType = "Event"; Message.Message = "Тестовый запрос"; LOG.AddString(Message); data = Encoding.ASCII.GetBytes("Success"); break; } mysocket.SendTo(data, data.Length, SocketFlags.None, _getHost(Remote.ToString())); string command = Console.ReadLine().ToString(); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } Console.WriteLine("Что бы закрыть сервер, нажмите Enter"); Console.ReadLine(); return; }
В Юнити при этом создан скриптик и повешен на объект на сцене.
Сервер принимает запрос и сообщает о том, что таковой произошёл. Парсит его успешно, всё прекрасно. Встаёт вопрос о том, как теперь вернуть данные в юнити... Строчка, которая теоретически должна слушать ответ приводит проект в зависание... Я понимаю, что методы работы в стандартных приложенияй, написанных на шарпе, отличаются от того, что происходит в Юнити, но всё таки хотелось бы понять, как это реализовать грамотно.
Заранее благодарю за любой совет!
Сразу отвечу на все вопросы, которые могут возникнуть: 1. Я не могу и не хочу использовать встроенную сеть Юнити,. 2. Я не хочу посмотреть в стороно Фотона и иже с ними.
Добавлено (02 Мар 2015, 17:26) --------------------------------------------- На стороне юнити выделил два отдельных экземпляра UdpClient Sender(23000) и Listener(23001); Sender свою задачу отрабатывает на ура, тогда как дело доходит до листенера он... Я подозреваю, что тоже отрабатывает, просто слушает без конца, в результате чего Юнити и зависает... Может как-то создать отдельный поток, независимый от графики и работать с сетью в нём? Если это решит вопрос, хо, хотелось бы понять, как это сделать...
Левша, благодарю за наводку, нашёл вот такую статейку, надеюсь, поможет... Перестал наследоваться от MonoBehaviour, всю логику вынес в отдельный класс. буду пробовать получать значения с сервера через него.
А по поводу встроенной сети. Она, увы, хоть и облегчает жизнь, но подразумевает, что сервер так же должен быть сделан на Юнити. Это, возможно, и не плохой вариант, так как позволяет просчитывать на нём хотя бы туже физику, но блин... Сервер с графической оболочкой? Я просто себе очень слабо представляю характеристики машины, на которой он должен будет работать... Это ж мало того, что там будет прорва оперативки и процессорных ядер, придётся ещё туда же впихивать видеокарту... У меня в голове это не очень укладывается
Добавлено (02 Мар 2015, 17:47) --------------------------------------------- Левша, а, если не секрет, в чём преимущество использования корутин, перед потоками?
если не секрет, в чём преимущество использования корутин, перед потоками?
В простоте использования. А так - это совсем не поток...
Цитата
Может как-то создать отдельный поток, независимый от графики и работать с сетью в нём? Если это решит вопрос, хо, хотелось бы понять, как это сделать...
Как обычно при работе с потоками. Единственно - из своего потока нельзя использовать Unity методы. Т.е. типа - результаты нужно куда то складывать, откуда в Юнити можно будет их получить...
Вообще, если интересно - смотри клиент Фотона. Он прекрасно декомпилируется. Там все построено на System.Net System.Net.Sockets А потоки используются в основном для асинхронности послания и приема информации
seaman, благодарю. Попробую Прочитал про корутины, думаю, они всё же не совсем то, что мне нужно. Как вернуть из асинхронного потока данные я придумаю. Но, может ещё иначе решу вопрос...