質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
C#

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

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

4回答

2352閲覧

Websocket通信を行うサーバー側のGUIアプリを作りたい

alicealice

総合スコア5

C#

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

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2020/10/12 12:30

##前提・実現したいこと

C#超初心者です。
WindowsFormでWebsocket通信を行うアプリ(サーバーサイド)を作ろうとしています。クライアントとの通信状態をテキストボックスに表示させる処理を実装したく下記のようなコードを書いたのですが、エラーが出てしまいます。

インスタンスの呼び出し方法に誤りがあると思われるのですが、エラーの原因と対策を教えて頂けないでしょうか。
未熟すぎる質問で恐縮ですが、どなたかご教授いただければ幸いです。よろしくお願いいたします。

##発生している問題・エラーメッセージ

System.NullReferenceException: 'オブジェクト参照がオブジェクト インスタンスに設定されていません。'

sample_websocketGUI.Form1.hoge.get が null を返しました。

##該当のソースコード(Form1.cs)

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using WebSocketSharp; 11using WebSocketSharp.Net; 12using WebSocketSharp.Server; 13 14namespace sample_websocketGUI 15{ 16 public partial class Form1 : Form 17 { 18 19 //Hogeインスタンス保持用のプロパティ 20 public Hoge hoge { get; set;} 21 22 public Form1() 23 { 24 InitializeComponent(); 25 26 WebSocketServer server = new WebSocketServer(8080); //サーバの設立 27 server.AddWebSocketService<Hoge>("/", (Hoge hoge) => { this.hoge = hoge; }); //サーバの設定 28 29 server.Start(); 30 31 timer1.Enabled = true; //タイマを有効化 32 } 33 34 35 //テキストボックスに通信状態を表示、一定時間毎に更新するメソッド 36 private void timer1_Tick(object sender, EventArgs e) 37 { 38 textBox1.Text = hoge.getState().ToString(); 39 } 40 41 } 42 43 public class Hoge : WebSocketBehavior 44 { 45 46 //通信状態を取得するメソッド 47 public WebSocketState getState() 48 { 49 return ConnectionState; 50 } 51 52 } 53 54 55} 56

##補足情報(FW/ツールのバージョンなど)

以下のツール、ライブラリを使用

・WindowsForms (Windows 10 Pro)
・Websocket-sharp
https://github.com/sta/websocket-sharp

・テスト(クライアント側)
C:\Users*** >wscat -c ws://localhost:8080

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/10/13 02:41 編集

質問のタイトルだけ見ると、前回と同じ質問?と思ってしまうので、技術的にどういう問題か発生しているかが一目で判るタイトルを付けてください。 (タイマーでWebSocket通信状態監視時にNullReferenceException発生 とか) また、例外の詳細も載せるようにしてください。 例外発生時に、詳細のコピーでクリップボードにコピーできます。
guest

回答4

0

以下のように例外処理を入れました。

C#

1 private void timer1_Tick(object sender, EventArgs e) 2 { 3 try 4 { 5 textBox1.Text = hoge.getState().ToString(); 6 7 } 8 catch(System.NullReferenceException){ 9 textBox1.Text = "Closed"; 10 11 } 12 13 }

投稿2020/10/13 02:48

alicealice

総合スコア5

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

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

0

csharp

1(Hoge hoge) => { this.hoge = hoge; }

AddWebSocketServiceのこの処理は、実際に動作させた所、クライアントが接続した直後に呼ばれるようです。そのため、クライアントがまだ接続しない間は this.hoge は nullになります。
timer1の処理が実行された時点でクライアント未接続の場合、this.hoge はnullなのでNullReferenceExceptionになります。

NullReferenceExceptionを回避するだけなら、gentaroさんの回答にある対処療法でnullチェックを行うだけでいいと思いますが、リアルタイム性を上げるなら、タイマーそのものをやめて、Hogeクラスで OnOpen, OnClose メソッドをオーバーライドして、接続・切断時直後に状態を更新するのが良いかもしれません。

ちなみに、this.hoge にHogeクラスのインスタンスを記憶させるのは、1:1の通信の場合は上手くいくと思いますが、複数のクライアントが接続してきた場合、新しい接続がある毎にHogeクラスのオブジェクトが作成されるので、this.hoge がどのクライアントか判別できない問題が発生します。
データの持ち方も良く考える必要があるかもしれません。(もしくはFormに持たないか)

投稿2020/10/13 02:25

編集2020/10/13 02:35
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

alicealice

2020/10/13 02:45

いつもご回答いただきありがとうございます! 自分でも色々検証しましたが、ご指摘の通り一度接続されるまでAddwebsocketserviceが呼ばれないことに気づきました。 確かにOnOpen, OnClose メソッドを用いた方が早いですね。難しく考えすぎていました… データの持ち方については、今回は1:1を想定しているのでとりあえず今の方法で実装しようと思います。
guest

0

ベストアンサー

インスタンスの呼び出し方法に誤りがあると思われるのですが、エラーの原因と対策を教えて頂けないでしょうか。

何のインスタンスの「呼び出し方法」についての話なのかわかりませんが…

c#

1public Hoge hoge { get; set;}

は宣言されているだけで初期化されていません。
なので、このプログラム開始時点ではnullです。
この状態でhogeにアクセスするとNullReferenceExceptionが発生します。
ここまでOKですか?

で、おそらく

c#

1server.AddWebSocketService<Hoge>("/", (Hoge hoge) => { this.hoge = hoge; }); //サーバの設定

という箇所でインスタンスがセットされる事を期待されているんでしょうけど、this.hoge = hoge;の箇所が実行されるタイミングがコードを見る限りではわかりません。

いずれどこかのタイミングでこの処理が実行されるとしても、実行前に

c#

1textBox1.Text = hoge.getState().ToString();

この処理を通ったら例外が発生します。

対処療法なら

c#

1if (hoge != null) 2 textBox1.Text = hoge.getState().ToString();

で、とりあえず例外の発生は無くなると思いますが。

投稿2020/10/12 12:55

gentaro

総合スコア8947

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

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

alicealice

2020/10/13 02:37

ご回答ありがとうございます! (Hoge hoge) => { this.hoge = hoge; }でインスタンス生成されていると思っていましたが、サーバーを立てた直後はこの処理が呼ばれてないですね… ご指摘の通り例外処理を行うことで応急処置をしました。
guest

0

hoge のインスタンス生成行ってない/初期化してないのでnullですね

投稿2020/10/12 12:35

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問