"Если вдруг открылся люк, не пугайся, это глюк!" (с) Если что-то работает не так, вы нашли ошибку или опечатку в программе — вам в этот раздел
AbaiAkzhigitow
Доброго времени суток! Прошу помощи.
Наблюдается следующая проблема: клиенты в локальной сети спустя некоторое время после подключения, отключаются от сервера с ошибкой следующего вида:
[13:11:24] [ERROR] Сетевая ошибка №10054: "Connection reset by peer" и дальнейшие попытки подключения к серверу не удаются. Соединение восстанавливается, только если приложение клиента закрыть и запустить снова.
Аватара пользователя
Алексей Пикуров
Добрый день. Версия 7.7?
Аватара пользователя
Алексей Пикуров
Сами по себе клиенты отвалиться не могут. Есть причина. Зайдите в админку, раздел "Инструменты", "Просмотр протоколов" и посмотрите логи.
nicola.vaccai
В логах на сервере следующие сетевые ошибки:
Код: Выделить всё
[11:00:00:847   1]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "39", IP: "192.168.1.1", ClientType: "win32", HWID: "43C4210841F1D542C3B67743D42542D4845641541F2E2D16"
---------------------
[11:00:31:936   4]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "3", IP: "192.168.1.1", ClientType: "win32", HWID: "45940B7D2E2D43C211654504354F412001F250B522740F0E"
---------------------
[13:11:41:953   1]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "1", IP: "192.168.1.1", ClientType: "win32", HWID: "585D401230E44A7E07419420A507B020C6A7E42B982F"
[13:43:26:996   4]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "1", IP: "192.168.1.1", ClientType: "win32", HWID: "585D401230E44A7E07419420A507B020C6A7E42B982F"

 ---------------------

[17:34:03:023   2]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "6", IP: "192.168.1.1", ClientType: "win32", HWID: "26445201C6B6445FAC4035F203A5B1642D3A1920395244B491456"
[18:38:18:550   4]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "6", IP: "192.168.1.1", ClientType: "win32", HWID: "26445201C6B6445FAC4035F203A5B1642D3A1920395244B491456"
[18:59:53:907   1]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "6", IP: "192.168.1.1", ClientType: "win32", HWID: "26445201C6B6445FAC4035F203A5B1642D3A1920395244B491456"
[19:15:08:215   2]: Ошибка #0085: сетевая ошибка (WINSOCK 10054) "Connection reset by peer", UIN: "6", IP: "192.168.1.1", ClientType: "win32", HWID: "26445201C6B6445FAC4035F203A5B1642D3A1920395244B491456
Аватара пользователя
Алексей Пикуров
"Connection reset by peer" — соединение прервано удалённой стороной. Но такое не может быть и для клиента, и для сервера. Значит, виновато что-то посредине между ними.

Смотрите свой файрвол и антивирус, фильтрующий трафик.

Как у вас организована сеть между сервером и клиентами?
nicola.vaccai
Сервер соединен с роутером проводным гигабитным соединением. Остальные клиенты подключаются к серверу по WiFi-сети. До недавнего времени таких обрывов соединения не наблюдалось. Скрипты не могут быть причиной отключений клиентов?
Аватара пользователя
Алексей Пикуров
Могут. Если вы их писали.
nicola.vaccai
Код: Выделить всё
// -----------------------------------------------------------------------------------
// ver 1.1 / Sep 22, 2017, (c) Alexey Pikurov, [email protected]
// ver 1.2 / Dec 20, 2018, (c) Alexandr
// -----------------------------------------------------------------------------------

function IsTextMessageType( iMsgType: integer): boolean;
begin
   result := false;
   case iMsgType of
       0: result := true;
       1: result := true;
       5: result := true;
       10: result := true;
       11: result := true;
       15: result := true;
       16: result := true;
       21: result := true;
    end;
end;

function OnPrivateMessage(iCID, iUIN, iUINTo, iMsgType: integer; sMsg: string): boolean;
var
  sID, sOutMsg, sNameFrom, s, sEmailTo, sEmailFrom, sTextBody, sTextFrom, sTextSubject: string;
  bResult, bSendMessage, bNotOnline: boolean;
  iState: integer;
begin
  result := true;
   
    bNotOnline := not mIsUINOnline(iUINTo);
    bSendMessage := bNotOnline;
   
    if not bSendMessage then begin
       iState := mGetUserState(iUINTo);
        if iState = 1 then begin
           bSendMessage := true;
       end;
    end;
   
    if bSendMessage then begin
      // get sender's Telegram ID
      sID := mIntegrationTelegramGetUserIDByUIN(iUINTo);
      sEmailTo   := mGetUserPrimaryEmail(iUINTo);
      sEmailFrom := mGetUserPrimaryEmail(iUIN);
      sNameFrom := mGetUserFullNameByPreset(iUIN, 0);
     
         //Если тип сообщения строка и сотрудник подключен к боту Telegram
        //то отправка будет через Telegram (файлы все равно на телеграм не попадают смысл их передавать)
        //Иначе если не в онлайне отправка на емайл
        if (sID[1] <> '-') and (IsTextMessageType(iMsgType) = true) then begin // no errors
         
          // convert MyChat message to plaint text
          sOutMsg := mConvertMsgToPlainText(sMsg, iMsgType);
         
          // add WEB support link and user display name to message
          sOutMsg := '<a href="' +
                     mGetServerExternalAddress(0) +
                     '/support/?uin=' +
                     IntToStr(iUIN) +
                     '&silent">' +
                     sNameFrom +
                     '</a>:' +
                     CRLF +
                     CRLF +
                     sOutMsg;
                     
          // send message to Telegram
          s := mIntegrationTelegramSendMessage(sID, sOutMsg, 5000);
          bResult := true;
         
            if JSONGetBoolean(s, 'ok', bResult) <> 0 then bResult := false;
           
            // if any error occured - log result to server's system scripts protocol
            if not bResult then mLogScriptToDisk(s);
        end
        else if (length(sEmailTo) > 0) and (bNotOnline) then begin
       
          sTextSubject := 'Сообщение из MyChat от '+sNameFrom + ' ' + FormatDateTime('[dd.mm.yyyy hh:nn:ss]', Now);
          if (length(sEmailFrom) > 0) then begin
              sTextFrom := '<a href="mailto:'+sEmailFrom+'">'+sNameFrom+'</a>';
          end
          else begin
              sTextFrom := sNameFrom;       
          end;   
         
          sTextBody := '<span style="color:blue">' +
                       FormatDateTime('[dd.mm.yyyy hh:nn:ss]', Now) +
                       '</span>' +
                       ' '+
                       '<span style="color:green"><b>' +
                    sTextFrom +
                       '</b></span>'+
                       '&gt; ';
                       
          if (IsTextMessageType(iMsgType) = true) then begin
             sTextBody := sTextBody + CRLF + ReplaceString(mConvertMsgToPlainText(sMsg, iMsgType), CRLF, '</br>', true, false);
          end
          else begin
             sTextBody := sTextBody + 'Вам был отправлен файл, но к большому сожалению функция передачи файла по емайлу еще не реализована'+CRLF+'</br>';
          end;
         
          mSendEmail(sEmailTo, sTextSubject, sTextBody, 1, '');
        end;
    end;
end;

begin

end.
nicola.vaccai
Код: Выделить всё
procedure SendBrowserInfo(iUIN, iUINTo, iCID, iCIDTo: integer);
var
  s, sIP, sWEBSupportBrowserInfo, sWEBSupportRefLink, sWEBSupportsSysLanguage, sWEBSupportsPlatformOS,
  sGeoIP, sCountry, sCity: string;
begin
  sIP                     := mGetCIDAttribute(iCID, 'IP');
  sWEBSupportBrowserInfo  := mGetCIDAttribute(iCID, 'UserAgent');
  sWEBSupportRefLink      := mGetCIDAttribute(iCID, 'Reflink');
  sWEBSupportsSysLanguage := mGetCIDAttribute(iCID, 'Lang');
  sWEBSupportsPlatformOS  := mGetCIDAttribute(iCID, 'OS');
   
  s := '-=УВЕДОМЛЕНИЕ ОНЛАЙН-ЧАТА "ДИАГНОСТ56.РФ"=-' + CRLF + CRLF +
       'IP-адрес клиента: ' + sIP;
     
    if length(sWEBSupportBrowserInfo) > 0 then s := s + CRLF + 'Браузер гостя: ' + sWEBSupportBrowserInfo + CRLF;
    if length(sWEBSupportRefLink) > 0 then s := s + CRLF + 'Пишет с сайта: ' + sWEBSupportRefLink;
    if length(sWEBSupportsSysLanguage) > 0 then s := s + CRLF + 'Язык системы: ' + sWEBSupportsSysLanguage;
    if length(sWEBSupportsPlatformOS) > 0 then s := s + CRLF + 'Платформа: ' + sWEBSupportsPlatformOS;
         
  sGeoIP   := GeoIPGetQuickInfo(sIP);
  sCountry := Fetch(sGeoIP, '|');
  sCity    := sGeoIP;
       
    if length(sCountry) > 0 then begin
      sGeoIP := sCountry;
           
        if length(sCity) > 0 then sGeoIP := sGeoIP + ', ' + sCity;
             
      s := s + CRLF + CRLF + sGeoIP; 
    end else sGeoIP := ''; 
     
  mSendPrivateMessage(iUIN, iUINTo, s, 21, true);
  mSendCustomMsgToClientConsoleByCID(iCIDTo, 'WEB support session from UIN ' + inttostr(iUIN), 'newmsg', false, true, 78);
end;

procedure SendHelloMessage(iUIN, iUINTo: integer);
var
  s: string;
  iHour: integer;
  dt: Double;
begin
  dt := Now;

    if DayOfTheWeek(dt) < 6 then begin
      iHour := HourOf(dt);
     
        if (iHour >= 8) and (iHour <= 16) then s := 'Здравствуйте, что Вас интересует?'
          else s := 'Здравствуйте! К сожалению, сейчас мы не сможем Вам ответить. Но Вы можете задать любой вопрос в этом чате, и мы пришлем ответ на указанный Вами e-mail в рабочее время (с 8:00 до 16:00)';
    end else s := 'Здравствуйте, мы работаем с понедельника по пятницу, с 8:00 до 16:00. Но Вы можете задать любой вопрос в этом чате, и мы пришлем ответ на указанный Вами e-mail';
 
  mSendPrivateMessage(iUINTo, iUIN, s, 1, true);
end;

function OnPrivateRequest(iCID, iUIN, iUINTo, iRole, iRoleReciever, iTask: integer): boolean;
var
  sKey, sKeyData, sDateNow: string;
  iWhat, iCIDTo: integer;
begin
  SetScriptTimeOut(10000); // на всякий случай, вдруг будет долго работать 

  if mGetRoleNameByID(iRole) = 'WEB guests' then begin
    iCIDTo := mGetUserCID(iUINTo);
   
    sKey := 'websupp' + IntToStr(iUIN) + '-' + IntToStr(iUINTo);
   
    //mDBStorageDeleteKey(sKey);
    //mDBStorageSetData(sKey, '123');
       
    sKeyData := mDBStorageGetData(sKey);
    sDateNow := FormatDateTime('ddmmyyyy', Now);
       
      if length(sKeyData) = 0 then iWhat := 1 // ни разу не подключался к серверу
        else if sKeyData = sDateNow then iWhat := 2 // уже подключался сегодня
            else iWhat := 3; // подключался раньше, не сегодня

    mDBStorageSetData(sKey, sDateNow);

      // юзер подключается первый раз и оператор онлайн
      if (iCIDTo <> -1) and (iWhat = 1) then begin
        SendBrowserInfo(iUIN, iUINTo, iCID, iCIDTo);
        SendHelloMessage(iUIN, iUINTo);
      end else
      // если пользователь подключается первый раз вообще либо впервые за день
      if (iWhat = 1) or (iWhat = 3) then SendHelloMessage(iUIN, iUINTo);
  end;

  result := true;
end;

begin

end.
Аватара пользователя
Алексей Пикуров
Обрамляйте текст скрипта тегом code, пожалуйста.
Аватара пользователя
Алексей Пикуров
Не надо вставлять всё подряд, что у вас есть, в форум :) Вы понимаете логику этих скриптов?
nicola.vaccai
Код: Выделить всё
// ---------------------------------------
// Script created by Alexey Pikurov
// 01.06.2018 15:33:51
// ---------------------------------------
const
PREFIX = '[Гость]';
 
procedure OnRegistered(iCID, iUIN: integer; var iRole: integer; var bBlocked: boolean);
var
  sGroupName, sNickName: string;
  sGuestEmail: string;
  x: integer;
begin
  sGroupName := mGetRoleNameByID(iRole);
 
    if sGroupName = 'WEB guests' then begin
      sNickName := mGetUserAttribute(iUIN, 'InternalNickName');
      sGuestEmail := mGetUserAttribute(iUIN, 'Email');
     
     
        if pos(PREFIX, sNickName) = 0 then mSetUserAttribute(iUIN, 'InternalNickName', + '<' + sGuestEmail + '>' + ' ' + PREFIX + ' ' + sNickName);
    end;
end;

begin

end.
nicola.vaccai
Активны описанные выше три скрипта. Были взяты на форуме и частично изменены.
Аватара пользователя
Алексей Пикуров
Хорошо. Отключите их и понаблюдайте. Действуйте методом исключения.
nicola.vaccai
Итог:
1) скрипты к отключениям клиентов не причастны
2) помогло увеличение интервала между переподключениями с 10 сек. до 60 секунд

Тему можно закрывать.
Аватара пользователя
Алексей Пикуров
Ок, благодарю вас за ответ.