WCF прекращает отвечать приблизительно после приблизительно 10 вызовов (регулировка)

Вам придется немного перестроить вещи, чтобы сделать это.

Идея заключается в том, что у вас есть пара глобальных переменных, которые обновляются обработчиками событий GPIOZero:

  • door_is_open - true, когда дверь открыта
  • [ 112] - подсчитывает количество секунд, в течение которых дверь была открыта (обработчики событий сбрасывают ее на ноль).

Существует также бесконечный основной цикл, который тикает один раз в секунду, который читает переменную door_is_open и увеличивает счетчик открытия ... и, наконец, если счетчик открытия достигает желаемого порога (5 секунд здесь, потому что мы ' нетерпеливые люди), он включает buzzer.

Обработчик door_closed заботится о сбросе buzzer, но это также может быть сделано в основном цикле.

Я также взял на себя смелость рефакторинга регистрации в свою собственную функцию, которая легко также печатает то же самое на консоли. (Кроме того, я бы предложил использовать форматирование даты ISO 8601, но я не хотел навязывать это здесь.)

Дальнейший рефакторинг может обернуть все это в аккуратный класс, чтобы избежать глобальных переменных. [ 1114]

(Это все в сухом коде, поэтому ваш пробег может отличаться, но идея должна работать. :))

import time
from gpiozero import Button, Buzzer


button = Button(21, pull_up=True)
buzzer = Buzzer(4)
door_is_open = False
door_open_counter = 0


def log_event(text):
    print(log_line)
    with open("log.txt", "a") as log_file:
        log_line = "%s | %s" % (time.strftime("%m-%d-%Y %X"), text)
        log_file.write(log_line + "\n")



def door_opened():
    global door_is_open
    global door_open_counter
    log_event("Opened")
    door_is_open = True
    door_open_counter = 0


def door_closed():
    global door_is_open
    global door_open_counter
    log_event("Closed")
    buzzer.off()
    door_is_open = False
    door_open_counter = 0


button.when_pressed = door_closed
button.when_released = door_opened

while True:
    time.sleep(1)
    if door_is_open:
        door_open_counter += 1
        if door_open_counter >= 5:
            buzzer.on()
39
задан John Saunders 25 August 2012 в 18:17
поделиться

4 ответа

Количество разрешенных одновременных подключений по умолчанию равно 10.
Скорее всего, ваш клиент не закрывает соединения.

Чтобы увеличить количество одновременных вызовов, вам придется добавить свое поведение в конфигурацию службы, а не клиента.

27
ответ дан markt 27 November 2019 в 02:52
поделиться

Можете ли вы настроить трассировку и запустить цикл? Может случиться так, что канал выйдет из строя и заставит клиента тайм-аут.

0
ответ дан JP Alioto 27 November 2019 в 02:52
поделиться

Нет, это неплохая идея, за исключением того, что вы все испортили.

Во-первых, вы пишете в строковый литерал. Это неопределенное поведение. (Он вылетает в Windows.) Если бы вы написали const char * str = "Hello!" , компилятор рявкнул бы на вас. К сожалению, существует (в C ++ устаревшее, но все же разрешенное) преобразование строкового литерала в неконстантный char * , что позволяет компилировать ваш код. Однако вам нужен массив, в который вы можете записывать (и который предварительно инициализирован). Для этого используйте char str [] = "Hello!" .

Другая, незначительная ошибка заключается в том, что вы дважды перебираете строку: strlen пробегает символы, пока не находит '\ 0' , а затем вы выполняете опять то же самое. Я действительно изменил свой вызов моей службы на Dispose () клиент службы, но, похоже, это не дало никакого эффекта. Очевидно, где-то скрывается еще один служебный вызов.

Что может быть интересно отметить, так это то, что заставило меня решить, что это , а не проблема: этот предел не связан с фактическим количеством сокетов, подключенных к веб-сервис. Когда вы достигнете предела maxConcurrentSessions , останется только одно фактическое соединение с сокетом . Я проверял это с помощью netstat , что привело меня к неправильному выводу. Итак, не путайте сеансы с сокетами .

У нас есть интерфейсы, определенные для всех наших сервисов WCF, поэтому я планирую адаптировать этот шаблон в своем коде сейчас:

IMyService service = new MyServiceClient();
using (service as IDisposable)
{
    service.MyServiceMethod();
}

Что также интересно, в том, что проблема не возникла у меня, когда службы (и веб-сайт) размещались на IIS. Конфигурация (почти) идентична, но мне не удалось воспроизвести такое поведение на этой машине. Думаю, это хорошо :)

@ John Saunders (о присвоении переменных в с использованием ):

Я обычно помещаю присвоение переменных в с использованием оператора . Но созданный IMyService не может быть неявно преобразован в IDisposable . Если бы вы действительно хотели, чтобы это присваивание было там, я полагаю, альтернативой будет:

IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}

Тем не менее, остается проблема с неправильной областью видимости переменной. Ссылка на службу IService непригодна для использования, но все еще остается в силе. Так что в этом отношении было бы лучше:

using (IDisposable serviceDisposable = new ServiceClient())
{
     IService service = (IService)serviceDisposable;
}

Это требует, чтобы я ввел дополнительное имя переменной. * Meh *

1
ответ дан 27 November 2019 в 02:52
поделиться

Это можно решить, создав класс singleton в качестве интерфейса между ссылкой на веб-сервис и приложением. Тогда будет создан только один экземпляр ссылки сервиса.

class ServiceInterface
{
     private static ServiceInterface  _instance;
     private ServiceClient _service = new ServiceClient ;
     private ServiceInterface()
     {
       //Prevent accessing default constructor
     }

     public static ServiceInterface GetInstance()
     {

     if(_instance == null)

     {

      _instance = new ServiceInterface();

    }

        return _instance;



 }


   // You can add your functions to access web service here

    Public int PerformTask()
    {
         return _service.PerformTask();
    }
}
1
ответ дан 27 November 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: