ブログ

割とコンピュータよりの情報をお届けします。

2019年4月24日

open62541の開発ブランチには互換性がない変更が加わった

以前にopen62541のビルドの記事(1, 2)を書いていたが,その時と異なりGitHubのリポジトリの先頭にはいよいよ次のリリースへ向けて(?)大きな変更が入ってしまった.

GitHubのリポジトリをクローンして使っていると昨年9月のころできていたことができなくなっている.
Server用とClient用の区切りを設けようとしているのか詳しくはわからないが,大きく仕様が変わっており,マニュアルも整っていないようなので,特にWindows用の対応は難しい.試行錯誤でうまく動かすような時間が必要である.

GitHubのリポジトリをクローンして使う場合には,最終リリース版である0.3を使用されることをお勧めする.
ちなみにhttps://open62541.org/では0.3.0の配布になっているのでそちらの方が適当であろう.
昨年9月までは新しい仕様を取り込もうとGitHubからクローンした方がバグフィックスが入っていて便利ということも間違いとは言い難かったが,0.3.0のリリース直前だったからで0.3.0のリリース後は次のリリースへ向けて積極的に変更が入っている.

ファイルの構造が変わって,open62541.hなどの一つのファイルをインクルードすれば足りたファイルがなくなってしまっている.そして,開発版のドキュメントではそれに対応していそうに見えたが,少なくともVisual Studioではライブラリのビルドは成功するのだが,それを使う段階でチュートリアルの方法では失敗する
時間がたてば,もう少し整理されてくるはず.オープンソースでまともに動くOPC-UAの実装の一つなので期待している.

≫ 続きを読む

2019/04/24 コンピュータ   TakeMe

HttpClientは標準でProxy経由の通信になる

.NET FrameworkでHttpClientを使う機会があった.何も気にせずに使い始めると通信にProxyの設定が適用される.

(2023.06.11 追記 下の例のアプリではHttpClientを1回しか使わないから問題ないが、短時間に複数回使用していく用途ではusingで囲うとリソースが枯渇するリスクが上がる。特に最新の.NET Coreや.NET 5.0以降の使用例ではDisposeせずに残している。記事内でKeepAliveなどを気にせずと書いているが、usingブロックから出るときにインスタンスが破棄されるため、KeepAliveなどが持続しないので注意。)

.NET Framework 4.5からの機能だとおもうが,HttpClientというものが使えるようになった.TcpClientでは気にする必要があるKeepAlive/Httpsなどの実装を気にせずに使用できるようだ.参考となるページはHttpClientクラスでWebページを取得するには?[C#、VB]であろうか.
(ただこの記事が書かれた時と状況が異なる点がSystem.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;の部分である.現在では脆弱性の懸念から,SSL 3やTLS1.1などが無効化され始めており,最初からTLS1.2でつなげに行かなければ失敗するサーバーが多くなっている点である.)
さて,外のサーバーに接続する場合には
HttpClientHandler handler = new HttpClientHandler();
handler.UseProxy = false;
もいらない(はずである).
しかし,ローカルにプロキシサーバーを設けている場合にはローカルアドレスに対してプロキシを使用しない設定にしても,http://192.168.1.1/などにリクエストを送ろうとすると,Windows の仕様(ほぼバグ)によりプロキシを経由しようとする.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // 取得したいWebページのURI
            Uri webUri = new Uri("https://www.valuestar.work/");

            // Call the method "GetWebPageAsync"
            Task<string> webTask = GetWebPageAsync(webUri);
            webTask.Wait(); // Mainメソッド内でawaitのかわりの待機
            string result = webTask.Result;  // content of the result 

            Console.WriteLine(result);
#if DEBUG
            Console.ReadKey();
#endif
        }

        static async Task<string> GetWebPageAsync(Uri uri)
        {
            // Forced to use TLS1.2
            System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;

            // Setting: "Do not use proxy"
            HttpClientHandler handler = new HttpClientHandler();
            handler.UseProxy = false;

            using (HttpClient client = new HttpClient(handler))
            {

                // setting timeout (optional)
                client.Timeout = TimeSpan.FromSeconds(10.0);

                try
                {
                    // Main part of this function
                    return await client.GetStringAsync(uri);
                }
                catch (HttpRequestException e)
                {
                    // Related to HTTP
                    Console.WriteLine("\nHTTP Exception");
                    Exception ex = e;
                    while (ex != null)
                    {
                        Console.WriteLine(ex.Message);
                        ex = ex.InnerException;
                    }
                }
                catch (TaskCanceledException e)
                {
                    // Timeout
                    Console.WriteLine("\nTimeout");
                    Console.WriteLine(e.Message);
                }
                catch (Exception e)
                {
                    // Others
                    Console.WriteLine(e.Message);
                }
                return null;
            }
        }
    }
}

困った問題である.http://127.0.0.1/などはループバックなのにプロキシを経由されるというほぼバグ仕様によりデバッグ中に相当苦労させられた.

≫ 続きを読む

2019/04/24 コンピュータ   TakeMe