🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

2回答

1592閲覧

C#, VB.NETのアプリ間通信(サーバー中継あり)で画面が止まる現象の調査、解決方法について

KZK1112

総合スコア8

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2019/11/05 05:40

編集2019/11/05 05:47

問題の概要

以下のような環境・構成で運用しているシステムがあります。
他社アプリから自社アプリへの連携動作時に画面が止まってしまう現象が発生して困っています。
似たような経験のある方のアドバイスや、調査方法等、教えて頂けたら幸いです。

環境

Windows7 または 10,.NET Framework 4.7.1,Linux(RedHatLinux7.6)

構成の説明

自社アプリの機能を他社アプリから呼び出す仕組みがあり、下のような構成を取っています。
A・B・Dは同一のWindowsPC上で動作し、CはLinuxサーバ上で動作します。

構成

A)他社デスクトップアプリ(C#.NETのWindows.Formsアプリ)
B)自社ライブラリ(VB.NETのDLL)…Aに組込みC・Dとの連携を担う
C)自社サーバアプリ(PHP, Perl)
D)自社デスクトップアプリ(VB.NETのWindows.Formsアプリ)

連携方式
  1. 処理の流れはA→B→C→D
  2. A→B:DLL組込みでメソッド呼出,戻り値受取
  3. B→C:HTTPリクエスト(GET),レスポンス受取
  4. C→D:Socket送信,受信

発生している問題

AがBのメソッド呼び出し
→BがCに通信
→CがDに通信
→DがCからの通知を受けて画面を表示する

という処理において、Dの画面表示イベント(From.Showメソッド実行後、Form.Loadイベント発生)処理前の段階で処理が停止し、メソッド戻り値を待っているAも画面が止まります。
画面は停止したままではなく、B→CのHTTPリクエストに設定した60秒のタイムアウトが過ぎると、Dの画面表示イベントが再開します。

この問題は毎回発生する訳ではなく、PC一台あたり毎日数十回以上繰り返される操作のうちに、数回発生する日もあれば、発生しない日もあります。

一度発生すると、Aを起動しなおすまでは同じ操作で再現します。
その状態でC→Dの部分のみ連携させると問題なく画面が表示されます。

止まっている状態でAを強制終了するとDの画面表示は即座に再開します。
また逆に、止まっている状態でDを強制終了するとAは即座に操作可能な状態に戻ります。
通信元と通信先で、互いに掴みあってロックしているような状態に見えます。
なかなか原因が特定できず、困っています。

該当のソースコード

※細かい部分は省略しています

A)他社デスクトップアプリ

C#

1public AppLink.AppLink App = null; 2App = new AppLink.AppLink(); 3string strRes = ""; 4strRes = App.Call(No);

B)自社ライブラリ・・・C)自社サーバアプリとhttp通信

VB

1Public Function Call(ByVal No As String) As String 2 'HttpWebRequestの作成 3 Dim sUrl As String = Settings.URL 4 sUrl = sUrl & "?no=" & No 5 Try 6 Dim req As HttpWebRequest = DirectCast(WebRequest.Create(sUrl), HttpWebRequest) 7 'サーバーからの応答を受信するためのWebResponseを取得 8 Dim res As System.Net.WebResponse = req.GetResponse() 9 Dim resStream As System.IO.Stream = res.GetResponseStream() 10 Dim sr As New System.IO.StreamReader(resStream) 11 Dim s As String = sr.ReadToEnd() 12 ' 読み込んだjsonをデシリアライズ 13 m_response = JsonConvert.DeserializeObject(Of apiResponse)(s) 14 sr.Close() 15 If m_response.result = apiResult.aNG Then 16 'サーバ内エラー時は"False"を返す 17 Log.WriteLog("sverr") 18 Return "False" 19 Else 20 '成功時はIDを返す 21 Return m_response.hogeID 22 End If 23 Catch ex As Exception 24 'サーバ通信不可時は"False"を返す 25 Log.WriteLog("neterr") 26 Return "False" 27 End Try 28End Function

D)自社デスクトップアプリ・・・C)自社サーバアプリとsocket通信

VB

1AddHandler Me.socketServer.ReceivedData, AddressOf server_ReceivedData 2 3Private Sub server_ReceivedData(ByVal sender As Object, ByVal e As ReceivedDataEventArgs) 4 Dim requestMsg As SocketRequestMsg = New SocketRequestMsg() 5 StatusCode = Event_Call(requestMsg) 6 'ステータスコード返信 7 e.Client.Send(StatusCode) 8End Sub 9 10Private Function Event_Call(ByVal requestMsg As SocketRequestMsg) 11 '画面表示 12 Invoke(New showfrmDelegate(AddressOf showfrm)) 13 return "200" 14End Funcion 15 16Delegate Sub showfrmDelegate() 17Sub showfrm() 18 Dim myFrm as frmHoge = New frmHoge 19 myFrm.Show(Me, False) 20End Sub 21 22Public Class frmHoge 23 Public Overloads Sub show(ByVal frm As frmMain, ByVal initialLoad As Boolean) 24 Me.TopMost = True 25 Me.Show() 26 Me.Activate() 27 End Sub 28End Class

試したこと

  • A)他社デスクトップアプリとB)自社ライブラリで.NET frameworkのコンパイルバージョンを合わせる(4.7.1)→効果なし
  • B)自社ライブラリのタイムアウト設定値を60秒から30秒に変更する→固まる時間が30秒に短縮された
  • B)自社ライブラリのタイムアウト時にexceptionのmessageをログ出力→「操作がタイムアウトしました」

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2019/11/05 06:56

画面が固まるのはUIスレッドで同期処理してるからのような気がするしそこは本題じゃなさそう。 どこで待たされているのかを特定するなら関係するソースにTraceログを仕込んで調査するのが普通だと思いますが。
hihijiji

2019/11/05 07:29

何が悪いって、設計が悪いです。 とりあえずC→Dの情報提供の仕方がネックです。 socket通信自体が悪いわけではないですが、そんなものをわざわざつくらず、 そこは出来合いのWebサービスでサクッと行きましょう。
YAmaGNZ

2019/11/05 13:23

実際にどのような通信が行われているのかwiresharkなどでパケットをキャプチャーしてみるとか
guest

回答2

0

「試したこと」にありませんが、なぜ PHP や Perl を疑ってないんでしょうか?
そもそもこの二つが併記されているところに強烈な地雷臭を感じます。

とりあえず B C D それぞれのテストプロジェクトを作成し、考えうるあらゆる状況を想定して徹底的にテストしてください。

画面はとりあえず気にしなくて大丈夫です。また連携も今は考える必要ありません。

それぞれのネットの読み書き部分を主コードから分離してファイルの読み書きと取り換えることができるようにし、テストはファイルで用意したなるべく意地悪なデータで行ってください。「通信するのは自社アプリだけだから」と、バリデーションに手を抜いているために、想定外のデータに対処できないというのはよくあることです。

たとえば現状では Call の中でネットワーク接続を作成し、JSON のシリアライズやエラーハンドリングを行っています。が、Call の役割は Stream を作って CallInternal(Stream, string) を呼び出すだけにとどめ、その他の処理はすべて CallInternal で行うようにすれば、テストプロジェクトから CallInternal に FileStream を渡すことで通信をシミュレーションできます。

それで問題が無くなれば今度は連結テストです。B C D を連携させるテストですが、この時も画面は使わず、ユーザーの入力は人間ではなくテストプロジェクトが作成したものを使ってください。

これらのテスト全てを通過する場合にのみ、UI を疑ってください。

投稿2019/11/05 22:28

Zuishin

総合スコア28669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/11/05 22:39

特にサーバー部分は、複数の接続を想定していなかったり、していてもロックの処理が甘いことがあります。単独データだけではなく、複数の接続に耐えるかというテストも行ってください。
guest

0

ただのカンですけど、CのPHPだかperlだかが
古いソケットを解放せずにDへの通信の度に新規接続を取得して上限まで達してるんじゃないのかな

Dの終了で復活するということはTCP通信かと思いますが
Dで「受信の度に新規接続が来てる」かつ「旧接続が有効のまま」ならば、ほぼ間違いなく解放漏れです。

投稿2019/11/06 03:59

asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asm

2019/11/06 04:04

岡崎図書館事件を思い出して類似事例として解説貼ろうと思ったが見つからない
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問