Шаблон для реализации heartbeat между сервером и клиентом

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

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

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

$connectionString = "Data Source=Apps2\Apps2;Initial Catalog=ICECAT;Integrated Security=SSPI"
$batchSize = 50000

# set up [files_index] datatable & read schema from DB
$files_index_table = New-Object System.Data.DataTable
$files_index_adapter = New-Object System.Data.SqlClient.SqlDataAdapter("SELECT * FROM files_index WHERE 0 = 1", $connectionString)
$files_index_adapter.Fill($files_index_table) | Out-Null
$files_index_bcp = New-Object SqlBulkCopy($connectionString)
$files_index_bcp.DestinationTableName = "dbo.files_index"
$files_index_count = 0

# set up [product_ids] datatable & read schema from DB
$product_ids_table = New-Object System.Data.DataTable
$product_ids_adapter = New-Object System.Data.SqlClient.SqlDataAdapter("SELECT * FROM product_ids WHERE 0 = 1", $connectionString)
$product_ids_adapter.Fill($product_ids_table) | Out-Null
$product_ids_bcp = New-Object System.Data.SqlClient.SqlBulkCopy($connectionString)
$product_ids_bcp.DestinationTableName = "dbo.product_ids"
$product_ids_count = 0

# main import loop
$xmlReader = New-Object System.Xml.XmlTextReader("C:\Scripts\icecat\files.index.xml")
while ($xmlReader.Read()) {
    # skip any XML nodes that aren't elements
    if ($xmlReader.NodeType -ne [System.Xml.XmlNodeType]::Element) { continue }

    # handle <file> elements
    if ($xmlReader.Name -eq "file") {
        $files_index_count++

        # remember current product ID, we'll need it when we hit the next <M_Prod_ID> element
        $curr_product_id = $xmlReader.GetAttribute("Product_ID")
        $is_new_file = $true

        $newRow = $files_index_table.NewRow()
        $newRow["Product_ID"] = $xmlReader.GetAttribute("Product_ID")
        $newRow["path"] = $xmlReader.GetAttribute("path")
        $newRow["Updated"] = $xmlReader.GetAttribute("Updated")
        $newRow["Quality"] = $xmlReader.GetAttribute("Quality")
        $newRow["Supplier_id"] = $xmlReader.GetAttribute("Supplier_id")
        $newRow["Prod_ID"] = $xmlReader.GetAttribute("Prod_ID")
        $newRow["Catid"] = $xmlReader.GetAttribute("Catid")
        $newRow["On_Market"] = $xmlReader.GetAttribute("On_Market")
        $newRow["Model_Name"] = $xmlReader.GetAttribute("Model_Name")
        $newRow["Product_View"] = $xmlReader.GetAttribute("Product_View")
        $newRow["HighPic"] = $xmlReader.GetAttribute("HighPic")
        $newRow["HighPicSize"] = $xmlReader.GetAttribute("HighPicSize")
        $newRow["HighPicWifiles_index_tableh"] = $xmlReader.GetAttribute("HighPicWifiles_index_tableh")
        $newRow["HighPicHeight"] = $xmlReader.GetAttribute("HighPicHeight")
        $newRow["Date_Added"] = $xmlReader.GetAttribute("Date_Added")
        $files_index_table.Rows.Add($newRow) | Out-Null

        if ($files_index_table.Rows.Count -eq $batchSize) {
            $files_index_bcp.WriteToServer($files_index_table)
            $files_index_table.Rows.Clear()
            Write-Host "$files_index_count <file> elements processed so far"
        }
    # handle <M_Prod_ID> elements
    } elseif ($xmlReader.Name -eq "M_Prod_ID") {
        $product_ids_count++

        # add self-reference row to the [product_ids] table
        # only for the first <M_Prod_ID> per <file> we need to do this
        if ($is_new_file) {
            $newRow = $product_ids_table.NewRow()
            $newRow["Product_ID"] = $curr_product_id  # from above
            $newRow["Alternative_ID"] = $curr_product_id
            $product_ids_table.Rows.Add($newRow) | Out-Null
            $is_new_file = $false
        }

        $newRow = $product_ids_table.NewRow()
        $newRow["Product_ID"] = $curr_product_id  # from above
        $newRow["Alternative_ID"] = $xmlReader.Value
        $product_ids_table.Rows.Add($newRow) | Out-Null

        if ($product_ids_table.Rows.Count -eq $batchSize) {
            $product_ids_bcp.WriteToServer($files_index_table)
            $product_ids_table.Rows.Clear()
            Write-Host "$product_ids_count <M_Prod_ID> elements processed so far"
        }
    }
}

# write any remaining rows to the server
if ($files_index_table.Rows.Count -gt 0) {
    $files_index_bcp.WriteToServer($files_index_table)
    $files_index_table.Rows.Clear()
}
Write-Host "$files_index_count <file> elements processed overall"

if ($product_ids_table.Rows.Count -gt 0) {
    $product_ids_bcp.WriteToServer($product_ids_table)
    $product_ids_table.Rows.Clear()
}
Write-Host "$product_ids_count <M_Prod_ID> elements processed overall"
6
задан GEOCHET 23 April 2009 в 16:09
поделиться

3 ответа

О каком клиенте идет речь? Windows-клиент или asp.net? Есть два очень общих шаблона для этого. Вы можете нажать или потянуть данные. Нажатие не работает, если в Интернете вы столкнетесь с брандмауэрами и натсами. Таким образом, вы получаете третий вариант, когда клиент инициирует соединение, а сервер оставляет соединение открытым для отправки информации туда и обратно.

Вам нужно предоставить гораздо больше информации, мы говорим об Интернете или интрасети? На какие .net Framework вы ориентируетесь? Сколько клиентов вы говорите? Решение, которое может обслуживать дюжину клиентов (особенно в модели push или третьей модели), может сильно отличаться от решения, которое может масштабироваться до тысяч клиентов.

Самое простое решение - это опрос со стороны клиента, Который, если вы не хотите, чтобы сервер имел мгновенное общение с клиентом, это путь. И сердцебиение - это не мгновенное общение.

Редактировать

Хорошо, вы указали сокеты, вы действительно уверены, что хотите заняться программированием сетевого типа более низкого уровня? Почему бы не использовать существующие сетевые стратегии, такие как HTTP. Вы можете сделать простой сервис удаленного взаимодействия через HTTP, который позволит вам обходить межсетевые экраны. Или даже лучше, если ваш сервер является веб-сервером, тогда просто установите старый старый сервис XML.

У меня нет примеров, которыми я мог бы поделиться, но вокруг должно быть много.

Вы действительно уверены, что хотите заняться программированием сетевого типа более низкого уровня? Почему бы не использовать существующие сетевые стратегии, такие как HTTP. Вы можете сделать простой сервис удаленного взаимодействия через HTTP, который позволит вам обходить межсетевые экраны. Или даже лучше, если ваш сервер является веб-сервером, тогда просто установите старый старый сервис XML.

У меня нет примеров, которыми я мог бы поделиться, но вокруг должно быть много.

Вы действительно уверены, что хотите заняться программированием сетевого типа более низкого уровня? Почему бы не использовать существующие сетевые стратегии, такие как HTTP. Вы можете сделать простой сервис удаленного взаимодействия через HTTP, который позволит вам обходить межсетевые экраны. Или даже лучше, если ваш сервер является веб-сервером, тогда просто установите старый старый сервис XML.

У меня нет примеров, которыми я мог бы поделиться, но вокруг должно быть много.

1
ответ дан 17 December 2019 в 04:52
поделиться

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

Book Series - 
Book Title  - Distributed Computing
Chapter Title  - On the Impact of Fast Failure Detectors on Real-Time Fault-Tolerant Systems
First Page  - 354
Last Page  - 369
Copyright  - 2002
Author  - Marcos K. Aguilera
Author  - Gérard Le Lann
Author  - Sam Toueg
DOI  - 10.1007/3-540-36108-1_24
Link  - http://www.springerlink.com/content/e03yf4etbnle9728
Book Title  - Distributed Algorithms
Chapter Title  - Heartbeat: A timeout-free failure detector for quiescent reliable communication
First Page  - 126
Last Page  - 140
Copyright  - 1997
Author  - Marcos Kawazoe Aguilera
Author  - Wei Chen
Author  - Sam Toueg
DOI  - 10.1007/BFb0030680
Link  - http://www.springerlink.com/content/dj5n71hl17841416

Кроме того, из вопроса не ясно, но если речь идет о Java, отличный ресурс по этой теме: Введение в надежное распределенное программирование , с множеством отличных примеров кода.

2
ответ дан 17 December 2019 в 04:52
поделиться

Использование модели тяги, упомянутой Джошем, является самым простым подходом. Прежде всего, вы преодолеете множество проблем с безопасностью. Не нужно беспокоиться о клиентских брандмауэрах. Кроме того, вам не нужно беспокоиться о необходимости открытия одного и того же порта на каждом клиенте или открытия динамических портов и уведомления сервера о том, какой порт на каком клиенте используется.

Кроме того, вам не придется вести список подписчиков на сервере. Кроме того, вам не нужно беспокоиться об очистке списка подписчиков, если клиент отключается не очень чистым способом (сбой приложения, сбой питания и т. Д.).

По сути, простой опрос клиента на службу на сервере - это самый простой и чистый подход, ИМХО. Я использовал это несколько раз. Вы можете даже настроить интервал опроса, если захотите.

Редактировать:

Хотя я не могу предоставить справочный или примерный код, я опишу то, что делал в прошлом.

По сути, у меня был веб-сервис, который при запросе возвращал бы состояние системы. Этот веб-сервис явно работает на сервере. При запуске клиенты запускают отдельный поток, который каждые 30 секунд будет запрашивать веб-службу, чтобы узнать состояние серверной системы. Затем пользовательский интерфейс будет обновлен, чтобы указать это состояние. После выполнения этой задачи поток вернется в режим ожидания на 30 секунд. Время обновления можно было настроить с помощью файла конфигурации. Просто убедитесь, что ошибки перехватываются, чтобы в случае сбоя запроса к службе по причине, отличной от неработающего сервера, все приложение не зависало.

Хотя я не могу предоставить ссылку или пример кода, я опишу то, что я делал в прошлом.

По сути, у меня был веб-сервис, который при запросе возвращал бы состояние системы. Этот веб-сервис явно работает на сервере. При запуске клиенты запускают отдельный поток, который каждые 30 секунд будет запрашивать веб-службу, чтобы узнать состояние серверной системы. Затем пользовательский интерфейс будет обновлен, чтобы указать это состояние. После выполнения этой задачи поток вернется в режим ожидания на 30 секунд. Время обновления можно было настроить с помощью файла конфигурации. Просто убедитесь, что ошибки перехватываются, чтобы в случае сбоя запроса к службе по причине, отличной от неработающего сервера, все приложение не зависало.

Хотя я не могу предоставить ссылку или пример кода, я опишу то, что я делал в прошлом.

По сути, у меня был веб-сервис, который при запросе возвращал бы состояние системы. Этот веб-сервис явно работает на сервере. При запуске клиенты запускают отдельный поток, который каждые 30 секунд будет запрашивать веб-службу, чтобы узнать состояние серверной системы. Затем пользовательский интерфейс будет обновлен, чтобы указать это состояние. После выполнения этой задачи поток вернется в режим ожидания на 30 секунд. Время обновления можно было настроить с помощью файла конфигурации. Просто убедитесь, что ошибки перехватываются, чтобы в случае сбоя запроса к службе по причине, отличной от неработающего сервера, все приложение не зависало.

У меня был веб-сервис, который при запросе возвращал бы состояние системы. Этот веб-сервис явно работает на сервере. При запуске клиенты запускают отдельный поток, который каждые 30 секунд будет запрашивать веб-службу, чтобы узнать состояние серверной системы. Затем пользовательский интерфейс будет обновлен, чтобы указать это состояние. После выполнения этой задачи поток вернется в режим ожидания на 30 секунд. Время обновления можно было настроить с помощью файла конфигурации. Просто убедитесь, что ошибки перехватываются, чтобы в случае сбоя запроса к службе по причине, отличной от неработающего сервера, все приложение не зависало.

У меня был веб-сервис, который при запросе возвращал бы состояние системы. Этот веб-сервис явно работает на сервере. При запуске клиенты запускают отдельный поток, который каждые 30 секунд будет запрашивать веб-службу, чтобы узнать состояние серверной системы. Затем пользовательский интерфейс будет обновлен, чтобы указать это состояние. После выполнения этой задачи поток вернется в режим ожидания на 30 секунд. Время обновления можно было настроить с помощью файла конфигурации. Просто убедитесь, что ошибки перехватываются, чтобы в случае сбоя запроса к службе по причине, отличной от неработающего сервера, все приложение не зависало.

запускает отдельный поток, который каждые 30 секунд будет запрашивать веб-службу, чтобы узнать состояние серверной системы. Затем пользовательский интерфейс будет обновлен, чтобы указать это состояние. После выполнения этой задачи поток вернется в режим ожидания на 30 секунд. Время обновления можно было настроить с помощью файла конфигурации. Просто убедитесь, что ошибки перехватываются, чтобы в случае сбоя запроса к службе по причине, отличной от неработающего сервера, все приложение не зависало.

запускает отдельный поток, который каждые 30 секунд будет запрашивать веб-службу, чтобы узнать состояние серверной системы. Затем пользовательский интерфейс будет обновлен, чтобы указать это состояние. После выполнения этой задачи поток вернется в режим ожидания на 30 секунд. Время обновления можно было настроить с помощью файла конфигурации. Просто убедитесь, что ошибки перехватываются, чтобы в случае сбоя запроса к службе по причине, отличной от неработающего сервера, все приложение не зависало.

2
ответ дан 17 December 2019 в 04:52
поделиться
Другие вопросы по тегам:

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