Форум программистов, компьютерный форум, киберфорум
C#: Веб-сервисы, WCF
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
 Аватар для Hastin
40 / 32 / 7
Регистрация: 24.03.2016
Сообщений: 270

Консоль и сервисы

23.01.2017, 19:13. Показов 2399. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. У меня такой вопрос : Есть консоль, которая запускает n-нное кол-во сервисов. Есть база, которую выгребает в оперативку консоль (хост в общем, тот, что запускает сервисы ). Есть сервис регистрации. Всё реализовано на WFC. Юзер проходит регистрацию, отсылает сервису данные, если всё ок, мне нужно записать эти данные в лист, что вытянула консолька. Как это гуманно сделать, без **внокода? Я или устал, или не могу сообразить. Просто не хочется в сервисе лишний раз коннект делать отдельно к базе, ведь такой сервис не один. В консоли вытянул себе всё, и апдейт делаю раз в 10 минут, к примеру. Буду рад, если подскажете как быть. Не соображаю вообще что-то. Спасибо

Добавлено через 23 минуты
Где то слышал, что есть какие-то события, и на них можно "подписаться". Можно было бы сделать в консоли (хосте) "подпись" на такое событие, и когда регистрация проходит, что бы консоль сама "спрашивала" с сервиса данные. Только как и что я не знаю :С Хелп

В целом, почему я хочу реализовать всё через консоль, а не прямо в сервисах. Потому что, всё завязано на одной бд, а мне, может понадобиться выключать отдельно каждый сервис, или включать по новой.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.01.2017, 19:13
Ответы с готовыми решениями:

Web-сервисы в VS2010
Как создать Web-сервисы в VS2010 ? В 2008 студии можно создать веб-сервис, а вот в VS2010 не магу найти, даже не магу открыть веб-сервисы...

Веб-сервисы и WCF передача данных
День добрый столкнулся с проблемой. Есть клиентская часть и серверная Серверная получает выборку из БД и передает на клиента выборку (...

Как правильнее описывать сервисы с учетом MVVM?
Я раньше вообще всю логику плодил внутри сервиса, но перейдя на MVVM я начал делать вот так: делаю у сервиса события соответствующие...

26
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
24.01.2017, 13:05
Студворк — интернет-сервис помощи студентам
Hastin, ну в общем я обдумал вашу затею. Кое-что пришло в голову, попробую абстрактно набросать вам свою идею, а там дальше уже сами разовьете как вам надо. Чуть позже покажу, что я придумал.
0
 Аватар для Hastin
40 / 32 / 7
Регистрация: 24.03.2016
Сообщений: 270
24.01.2017, 14:29  [ТС]
insite2012, о, спасибо большое Жду с нетерпением
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
24.01.2017, 19:46
Лучший ответ Сообщение было отмечено Hastin как решение

Решение

Hastin, итак, приступим. Я не претендую на оригинальность (и скорее всего, в моем примере есть масса недочетов), но это то, что мне пришло в голову.
Для начала, определим класс для всех параметров, которые требуются для запуска бота. Его код ниже, он сейчас пуст, вы сами его наполните нужными вам свойствами, исходя из вашей логики.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Hastin_Demo {
    /// <summary>
    /// Класс коллекции параметров для запуска бота
    /// </summary>
    public class BotParameterCollection {
        //Сюда добавить нужное количество параметров для запуска бота
    }
}
Далее, определим для нашего бота интерфейс. Каждый экземпляр бота будет его реализовывать. Код ниже.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
 
namespace Hastin_Demo {
    /// <summary>
    /// Интерфейс бота
    /// </summary>
    public interface IBot {
        /// <summary>
        /// Состояние бота
        /// </summary>
        BotState State { get; }
 
        /// <summary>
        /// Метод запуска бота
        /// </summary>
        /// <param name="parameters">Параметры для запуска бота</param>
        void Start(BotParameterCollection parameters);
 
        /// <summary>
        /// Метод остановки бота
        /// </summary>
        void Stop();
    }
 
    /// <summary>
    /// Перечисление состояния бота
    /// </summary>
    [DataContract]
    public enum BotState {
        /// <summary>
        /// Активен
        /// </summary>
        [EnumMember]
        ACTIVE,
        /// <summary>
        /// Не активен
        /// </summary>
        [EnumMember]
        UNACTIVE
    }
}
Теперь для примера реализуем этот интерфейс уже непосредственно в тестовом классе бота. Тут вам нужно реализовать всю логику его работы, и заполнить основные методы запуска и остановки бота. Вот тестовый код реализации.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#define TEST
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Hastin_Demo {
    /// <summary>
    /// Класс бота
    /// </summary>
    public class Bot : IBot {
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="id"></param>
        public Bot() {
            State = BotState.UNACTIVE;
        }
 
        /// <summary>
        /// Свойство состояния бота
        /// </summary>
        public BotState State { get; private set; }
 
        /// <summary>
        /// Запуск бота
        /// </summary>
        /// <param name="parameters"></param>
        public void Start(BotParameterCollection parameters) {
#if TEST
            Console.WriteLine("Start bot executing...");
#endif
            //Меняем состояние бота на активное
            State = BotState.ACTIVE;
            //Тут создаем и запускаем нашего бота, как требуется...
        }
 
        /// <summary>
        /// Остановка бота
        /// </summary>
        public void Stop() {
            //Тут останавливаем бота (все его таймеры-потоки и т.д.).
#if TEST
            Console.WriteLine("Stop bot executing...");
#endif
        }
    }
}
Теперь напишем контракт нашей службы. В нем четыре метода, два отвечают за авторизацию/регистрацию, и два - за запуск и остановку определенного бота. Вот код контракта.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
 
namespace Hastin_Demo {
    /// <summary>
    /// Контракт службы
    /// </summary>
    [ServiceContract]
    public interface IBotService {
        /// <summary>
        /// Авторизация
        /// </summary>
        /// <param name="username">Имя пользователя</param>
        /// <param name="password">Пароль</param>
        /// <returns>Мдентификатор пользователя</returns>
        [OperationContract]
        string Login(string username, string password);
 
        /// <summary>
        /// Регистрация
        /// </summary>
        /// <param name="username">Имя пользователя</param>
        /// <param name="password">Пароль</param>
        /// <returns>Идентификатор пользователя</returns>
        [OperationContract]
        string Register(string username, string password);
 
        /// <summary>
        /// Запуск бота
        /// </summary>
        /// <param name="parameters">Параметры запуска бота</param>
        /// <param name="userId">Идентификатор пользователя</param>
        [OperationContract]
        void StartBot(BotParameterCollection parameters, string userId);
 
        /// <summary>
        /// Остановка бота
        /// </summary>
        /// <param name="userId">Идентификатор пользователя</param>
        [OperationContract]
        void StopBot(string userId);
    }
}
Теперь реализуем контракт службы. Служба настроена как синглетная и многопоточная, то есть экземпляр службы у нас будет всего один, к которому будут обращаться все клиенты, желающие запустить или остановить бота. В службе есть коллекция ботов (типа словаря), в котором хранятся все работающие в данный момент боты. Пользователь может подключиться, запустить своего бота и отключиться, а через какое-то время подключиться снова и остановить своего бота. Код службы ниже.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
 
namespace Hastin_Demo {
    /// <summary>
    /// Реализация контракта службы
    /// </summary>
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, 
        ConcurrencyMode=ConcurrencyMode.Multiple)]
    public class BotService : IBotService {
        //Коллекция экземпляров ботов
        private Dictionary<string, IBot> botsCollection = 
            new Dictionary<string, IBot>();
 
        /// <summary>
        /// Авторизация пользователя
        /// </summary>
        /// <param name="username">Имя пользователя</param>
        /// <param name="password">Пароль</param>
        /// <returns>Идентификатор пользователя</returns>
        public string Login(string username, string password) {
            //Тут используем класс для работы с базой данных
            try {
            }
            catch (Exception ex) {
                FaultException error = new FaultException(ex.Message);
                throw error;
            }
            return "";
        }
 
        /// <summary>
        /// Регистрация пользователя
        /// </summary>
        /// <param name="username">Имя пользователя</param>
        /// <param name="password">Пароль</param>
        /// <returns>Идентификатор пользователя</returns>
        public string Register(string username, string password) {
            //Тут используем класс для работы с базой данных
            try {
            }
            catch (Exception ex) {
                FaultException error = new FaultException(ex.Message);
                throw error;
            }
            return "";
        }
 
        /// <summary>
        /// Запуск бота
        /// </summary>
        /// <param name="parameters">Параметры для запуска бота</param>
        /// <param name="userId">Идентификатор пользователя</param>
        public void StartBot(BotParameterCollection parameters, string userId) {
            try {
                //Проверка наличия работающего бота данного пользователя
                //и его остановка/удаление из коллекции
                if (botsCollection.ContainsKey(userId) && botsCollection[userId].State == BotState.ACTIVE) {
                    botsCollection[userId].Stop();
                    botsCollection.Remove(userId);
                }
                //Создание и запуск бота
                IBot bot = new Bot();
                botsCollection.Add(userId, bot);
                bot.Start(parameters);
            }
            catch (Exception ex) {
                FaultException error = new FaultException(ex.Message);
                throw error;
            }
        }
 
        /// <summary>
        /// Остановка бота
        /// </summary>
        /// <param name="userId">Идентификатор пользователя</param>
        public void StopBot(string userId) {
            try {
                //Проверяем наличие бота в коллекции
                if (!botsCollection.ContainsKey(userId)) {
                    return;
                }
                //Останавливаем бота и удаляем его из коллекции
                botsCollection[userId].Stop();
                botsCollection.Remove(userId);
            }
            catch (Exception ex) {
                FaultException error = new FaultException(ex.Message);
                throw error;
            }
        }
    }
}
Еще нам нужен вспомогательный класс для работы с базой данных, я сделал его прототип, код напишете свой. Примерная структура таблицы там есть, подгоните под свои желания.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Hastin_Demo {
    /*
     * ----- Вспомогательный класс для работы с базой пользователей -----
     * 
     * В данном классе реализуется логика для работы с базой пользователей.
     * Структура (приблизительная) таблицы Users показана ниже:
     * ---------------------------------------------------
     * |userid (string)|username(string)|password(string)|
     * ---------------------------------------------------
     * |               |                |                |
     * ---------------------------------------------------
     * |               |                |                |
     * ---------------------------------------------------
     * При запросе на авторизацию проверяется наличие пользователя с такими данными,
     * и при успешной проверке возвращается значение поля userid 
     * (типа Guid в строков представлении), созданное при регистрации.
     * При регистрации пользователя создается новая запись о пользователе 
     * (с предварительной проверкой, существует ли уже пользователь с таким именем),
     * после чего также возвращается значение поля-идентификатора.
    */
    public static class DatabaseHelper {
        public static string GetUserId(string username, string password) {
            return Guid.NewGuid().ToString();
        }
        public static string RegisterUser(string username, string password) {
            return Guid.NewGuid().ToString();
        }
    }
}
Ниже файл конфигурации службы.
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Hastin_Demo.BotService" behaviorConfiguration="serviceConfiguration">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8010/BotService"/>
          </baseAddresses>
        </host>
        <endpoint address="" 
                  binding="basicHttpBinding" 
                  contract="Hastin_Demo.IBotService"/>
        <endpoint address="mex" 
                  binding="mexHttpBinding" 
                  contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceConfiguration">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
Ну и непосредственно создание и запуск хоста.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
 
namespace Hastin_Demo {
    class Program {
        static void Main(string[] args) {
            using (ServiceHost host = new ServiceHost(typeof(BotService))) {
                host.Opening += new EventHandler(host_Opening);
                host.Opened += new EventHandler(host_Opened);
                host.Open();
                Console.ReadLine();
            }
        }
 
        static void host_Opened(object sender, EventArgs e) {
            Console.WriteLine("BotService is ready...");
        }
 
        static void host_Opening(object sender, EventArgs e) {
            Console.WriteLine("Opening BotService...");
        }
    }
}
Если что-то непонятно, в прикрепленном архиве полный код данного примера. Разбирайтесь.
Вложения
Тип файла: rar Hastin_Demo.rar (33.3 Кб, 4 просмотров)
2
 Аватар для Hastin
40 / 32 / 7
Регистрация: 24.03.2016
Сообщений: 270
24.01.2017, 23:30  [ТС]
insite2012, Спасибо большое, вы дали мне не слабую почву для размышлений Буду приступать к работе )
0
 Аватар для Hastin
40 / 32 / 7
Регистрация: 24.03.2016
Сообщений: 270
28.01.2017, 15:46  [ТС]
insite2012, У меня созрел такой вопрос, дабы не плодить темы, напишу сюда. А вот как насчёт обмена данными между серверов бота и клиентским приложением ? Например, бот сделал какое-то действие, как мне отобразить это в клиенте, если клиент того или иного пользователя запущен. Например, бот с кем-то сразился, и сообщить это в логе клиента.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
28.01.2017, 17:12
Цитата Сообщение от Hastin Посмотреть сообщение
как насчёт обмена данными между серверов бота и клиентским приложением ?
В классе бота событие, в службе при его создании подписка на это событие, и через коллбек выбрасывать сообщение клиенту. Коллбек односторонний, поскольку клиента может и не быть.
0
 Аватар для Hastin
40 / 32 / 7
Регистрация: 24.03.2016
Сообщений: 270
28.01.2017, 18:13  [ТС]
insite2012, а можно ссылочку на пример? Буду очень благодарен
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.01.2017, 18:13

Как получать изображения рабочего стола через сервисы
Получаю изображение вот так: Rectangle bounds = Screen.PrimaryScreen.Bounds; Bitmap screenshot = new...

Использование Sphinx4 jar в .NET через ikvm.net или веб сервисы?
Здравствуйте, Пытвюсь заставить распознаватель речи Sphinx 4 работать в .NET. Пробовал IKVM.NET и веб сервисы. Не одно решение...

Подготовить числа для вывода на консоль через ASCII и вывести на консоль
В регистре eax находится число, которое нужно превратить в ASCII-код и вывести на консоль символы, которые соответствуют полученному. ...

Программа выводит ответ и в консоль и в файл, хотя нужно только в консоль
когда выбираю вывести в консоль, программа выводит ответ и в консоль, и в файл #include &lt;stdio.h&gt; #define SIZE 101 ...

Не выводит текст в консоль, открывается пустая консоль без текста
Приложение должно вызывать консоль при выполнении каких то условий. В консоль записывается текст и ReadKey чтобы консоль не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru