netcore vue(electron) uds

netcore vue(electron) uds

前端

一、项目准备

  1. 创建项目
    $ vue create apricot-uds
    
    $ cd apricot-uds
    
  2. 安装依赖
    # 添加 electron-builder
    $ vue add electron-builder
    
    # socket.io
    $ npm install socket.io-client@2.3.0
    
  3. 项目配置
    # 集成 node
    const { defineConfig } = require('@vue/cli-service')
     module.exports = defineConfig({
     transpileDependencies: true,
     // 添加配置(集成node)、才能使用 fs 库
     pluginOptions: {
         electronBuilder: {
         nodeIntegration: true
         }
     }
     })
    
  4. 示例代码
    <template>
     <div class="hello">
         <label for="uds-server">uds-server</label>:
         <input
         name="uds-server"
         type="button"
         value="uds-server"
         v-on:click="udsServer"
         />
    
         <label for="uds-client">uds-client</label>:
         <input
         name="uds-client"
         type="button"
         value="uds-client"
         v-on:click="udsClient"
         />
     </div>
     </template>
    
     <script>
     var os = require("os");
    
     var path = require("path");
    
     var net = require("net");
    
     // 配置中文简体环境下,完整的时间格式
     const formatter = new Intl.DateTimeFormat("zh-CN", {
     year: "numeric",
     month: "long",
     day: "2-digit",
     hour: "2-digit",
     minute: "2-digit",
     second: "2-digit",
     fractionalSecondDigits: 3, // 包含毫秒
     hour12: false, // 使用24小时制
     });
    
     export default {
     name: "HelloWorld",
     props: {
         msg: String,
     },
     methods: {
         // server
         udsServer() {
         // uds server
         const server = net.createServer((socket) => {
             console.log("session connected.");
    
             // on data event
             socket.on("data", (data) => {
             console.log(" Received session data:", data.toString("utf-8"));
    
             socket.write("uds web server.");
             });
    
             // on end
             socket.on("end", () => {
             console.log("uds session end.");
             });
    
             // on error
             socket.on("error", (error) => {
             console.log("uds session error:", error);
             });
         });
    
         // windows、linux temp path
         var sockfile = this.getOSTempPath();
    
         // listen
         server.listen(sockfile, () => {});
         },
         // client
         udsClient() {
         // uds client
         const client = net.createConnection(
             {
             path: this.getOSTempPath(),
             },
             () => {
             console.log("connected to uds server.");
             }
         );
    
         // on connected
         client.on("connect", () => {
             console.log("uds connect");
         });
    
         // on error
         client.on("error", (err) => {
             console.log(err);
         });
    
         // on data
         client.on("data", (data) => {
             var now = new Date();
             console.log(
             `${formatter.format(now)} => client received data:${data.toString(
                 "utf-8"
             )}`
             );
         });
    
         // on end
         client.on("end", () => {
             console.log("uds end");
         });
    
         client.write(formatter.format(new Date()));
         },
         getOSTempPath() {
            // windows、linux
            if (os.platform() === "win32") {
               return path.join("\\\\?\\pipe\\", "chat.sock");
    
               // return path.join(os.tmpdir(), "chat.sock");
           } else if (os.platform() === "linux") return "/tmp/chat.socket";
         },
     },
     };
     </script>
    
     <!-- Add "scoped" attribute to limit CSS to this component only -->
     <style scoped>
     h3 {
     margin: 40px 0 0;
     }
     ul {
     list-style-type: none;
     padding: 0;
     }
     li {
     display: inline-block;
     margin: 0 10px;
     }
     a {
     color: #42b983;
     }
     </style>
    
  5. 运行项目
    $ npm run electron:serve
    
  6. 运行效果
  7. 本文源码

后端

一、项目准备

  1. 安装依赖
     > dotnet add package NetCoreServer --version 8.0.7
    
  2. 服务端
    • server ChatServer.cs
       public class ChatServer : UdsServer
       {
           public ChatServer(string path) : base(path) { }
      
           protected override UdsSession CreateSession() { return new ChatSession(this); }
      
           protected override void OnConnected(UdsSession session)
           {
               Console.WriteLine($"connected on session :{session.Id}");
               base.OnConnected(session);
           }
      
           protected override void OnError(SocketError error)
           {
             
               Console.WriteLine($"Chat Unix Domain Socket server caught an error with code {error}");
           }
      
           protected override Socket CreateSocket()
           {
               return new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
           }
      
           public override bool Multicast(byte[] buffer)
           {
               //Console.WriteLine($"Server received time:{DateTime.Now:mm:ss.fff}");
      
               //var content = System.Text.Encoding.UTF8.GetString(buffer);
      
               //Console.WriteLine(content);
      
               return true;
               //return base.Multicast(buffer);
           }
      
           public void SendToAllClients(byte[] buffer)
           {
               foreach (var session in Sessions)
               {
                   session.Value.SendAsync(buffer, 0, buffer.Length);
               }
           }
      }
      
    • session ChatSession.cs
      public class ChatSession : UdsSession
      {
          public ChatSession(UdsServer server) : base(server)
          {
          }
      
          protected override void OnConnected()
          {
      
              Console.WriteLine($"Server OnConnected time:{DateTime.Now:mm:ss.fff}");
      
      
              Console.WriteLine($"Chat Unix Domain Socket session with Id {Id} connected!");
      
              // Send invite message
              //string message = "Hello from Unix Domain Socket chat! Please send a message or '!' to disconnect  the client!";
      
              using var fileStream = Assembly.GetEntryAssembly().GetManifestResourceStream("Apricot.Uds.Server.2fdda3cc7cd98d1001e9f6a7b36eaf0e7bec54e73a51.jpg");
      
              var memeoryStream = new MemoryStream();
      
              fileStream.CopyTo(memeoryStream);
      
              var data = memeoryStream.ToArray();
      
              Console.WriteLine($"Server Start Send time:{DateTime.Now:mm:ss.fff}");
      
              SendAsync(data);
      
              Console.WriteLine($"Server Send End time:{DateTime.Now:mm:ss.fff}");
          }
      
          protected override void OnDisconnected()
          {
              Console.WriteLine($"Chat Unix Domain Socket session with Id {Id} disconnected!");
          }
      
          protected override void OnReceived(byte[] buffer, long offset, long size)
          {
              Console.WriteLine($"Server received time:{DateTime.Now:mm:ss.fff}");
      
              var content = System.Text.Encoding.UTF8.GetString(buffer);
      
              Console.WriteLine(content);
      
              using var fileStream = Assembly.GetEntryAssembly().GetManifestResourceStream("Apricot.Uds.Server.2fdda3cc7cd98d1001e9f6a7b36eaf0e7bec54e73a51.jpg");
      
              var memeoryStream = new MemoryStream();
      
              fileStream.CopyTo(memeoryStream);
      
              var data = memeoryStream.ToArray();
      
              Console.WriteLine($"client start send time:{DateTime.Now:mm:ss.fff}");
      
              this.Send(Convert.ToBase64String(buffer));
      
              Console.WriteLine($"client end send time:{DateTime.Now:mm:ss.fff}");
      
      
              // Multicast message to all connected sessions
              //Server.Multicast(message);
      
              // If the buffer starts with '!' the disconnect the current session
              if (content == "!")
                 Disconnect();
          }
      
          protected override void OnError(SocketError error)
          {
              Console.WriteLine($"Chat Unix Domain Socket session caught an error with code {error}");
          }
      }
      
    • main Program.cs
      string path = GetSocketPath();
      
      Console.WriteLine("Server started waiting for client to connect...");
      
      // Unix Domain Socket path
      //string path = Path.Combine(Path.GetTempPath(), "chat.sock");
      if (args.Length > 0)
          path = args[0];
      
      Console.WriteLine($"Unix Domain Socket server path: {path}");
      
      Console.WriteLine();
      
      // Create a new Unix Domain Socket chat server
      var server = new ChatServer(path);
      
      // Start the server
      Console.Write("Server starting...");
      
      server.Start();
      Console.WriteLine("Done!");
      
      Console.WriteLine("Press Enter to stop the server or '!' to restart the server...");
      
      // Perform text input
      for (; ; )
      {
          string line = Console.ReadLine();
          if (string.IsNullOrEmpty(line))
              break;
      
          // Restart the server
          if (line == "!")
          {
              Console.Write("Server restarting...");
              server.Restart();
              Console.WriteLine("Done!");
              continue;
          }
      
          // Multicast admin message to all sessions
          line = "(admin) " + line;
      
          server.SendToAllClients(Encoding.UTF8.GetBytes(line));
      }
      
      // Stop the server
      Console.Write("Server stopping...");
      server.Stop();
      Console.WriteLine("Done!");
      
      
      // sock path
      static string GetSocketPath()
      {
          if (OperatingSystem.IsWindows())
          {
              return Path.Combine(Path.GetTempPath(), "chat.sock");// @"\\?\pipe\chat.sock";
          }
          else
          {
              return "/tmp/electron-csharp.sock";
          }
      }
      
  3. 客户端
    • client ChatClient.cs
      public class ChatClient : NetCoreServer.UdsClient
      {
          public ChatClient(string path) : base(path) { }
      
          public void DisconnectAndStop()
          {
              _stop = true;
              DisconnectAsync();
              while (IsConnected)
                  Thread.Yield();
          }
      
          protected override void OnConnected()
          {
              Console.WriteLine($"Chat Unix Domain Socket client connected a new session with Id {Id}");
          }
      
          protected override Socket CreateSocket()
          {
              return new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
          }
      
          protected override void OnDisconnected()
          {
      
              Console.WriteLine($"Chat Unix Domain Socket client disconnected a session with Id {Id}");
      
              // Wait for a while...
              Thread.Sleep(1000);
      
              // Try to connect again
              if (!_stop)
                 ConnectAsync();
          }
      
      
          protected override void OnReceived(byte[] buffer, long offset, long size)
          {
              Console.WriteLine($"client receive time:{DateTime.Now:mm:ss.fff}");
              var content = Encoding.UTF8.GetString(buffer, (int)offset, (int)size);
      
              Console.WriteLine(content);
      
              if (content.StartsWith("(admin)"))
              {
                  using var fileStream = System.IO.File.OpenRead("C:\\Users\\Administrator\\Desktop\\2fdda3cc7cd98d1001e9f6a7b36eaf0e7bec54e73a51.jpg");
      
                  var memeoryStream = new MemoryStream();
      
                  fileStream.CopyTo(memeoryStream);
      
                  var data = memeoryStream.ToArray();
      
                  Console.WriteLine($"client start send time:{DateTime.Now:mm:ss.fff}");
      
                  this.Send(Convert.ToBase64String(buffer));
      
                  Console.WriteLine($"client end send time:{DateTime.Now:mm:ss.fff}");
              }
             
          }
      
          protected override void OnError(SocketError error)
          {
              Console.WriteLine($"Chat Unix Domain Socket client caught an error with code {error}");
          }
      
          private bool _stop;
      }
      
    • main Program.cd
      
      var path = GetSocketPath();
      
      Console.WriteLine($"Unix Domain Socket server path: {path}");
      
      Console.WriteLine();
      
      // Create a new Unix Domain Socket chat client
      var client = new ChatClient(path);
      
      // Connect the client
      Console.Write("Client connecting...");
      client.ConnectAsync();
      Console.WriteLine("Done!");
      
      Console.WriteLine("Press Enter to stop the client or '!' to reconnect the client...");
      
      // Perform text input
      for (; ; )
      {
          string line = Console.ReadLine();
          if (string.IsNullOrEmpty(line))
              break;
      
          // Disconnect the client
          if (line == "!")
          {
              Console.Write("Client disconnecting...");
              client.DisconnectAsync();
              Console.WriteLine("Done!");
              continue;
          }
      
          // Send the entered text to the chat server
          client.SendAsync(line);
      }
      
      // Disconnect the client
      Console.Write("Client disconnecting...");
      client.DisconnectAndStop();
      Console.WriteLine("Done!");
      
  4. 参考

说在最后

  1. 环境支持

    客户端 / 服务端 windows linux
    vue client / vue server
    C# client / C# server
    vue client / C# server
  2. 遗留问题 windows 环境

    • 前端错误:Uncaught Error: listen EACCES: permission denied

    • 后端错误:套接字操作遇到了一个已死的网络

posted @ 2025-11-05 16:30  1764564459  阅读(4)  评论(0)    收藏  举报