forked from ElectronNET/Electron.NET
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathIpcMain.cs
More file actions
158 lines (143 loc) · 5.87 KB
/
IpcMain.cs
File metadata and controls
158 lines (143 loc) · 5.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
namespace ElectronNET.API
{
using System;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using ElectronNET.Serialization;
/// <summary>
/// Communicate asynchronously from the main process to renderer processes.
/// </summary>
public sealed class IpcMain
{
private static IpcMain _ipcMain;
private static object _syncRoot = new object();
private static readonly JsonSerializerOptions BoxedObjectSerializationOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
WriteIndented = false,
Converters =
{
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
new JsonToBoxedPrimitivesConverter(),
}
};
internal IpcMain()
{
}
internal static IpcMain Instance
{
get
{
if (_ipcMain == null)
{
lock (_syncRoot)
{
if (_ipcMain == null)
{
_ipcMain = new IpcMain();
}
}
}
return _ipcMain;
}
}
/// <summary>
/// Listens to channel, when a new message arrives listener would be called with
/// listener(event, args...).
/// </summary>
/// <param name="channel">Channelname.</param>
/// <param name="listener">Callback Method.</param>
public async Task On(string channel, Action<object> listener)
{
await BridgeConnector.Socket.Emit("registerIpcMainChannel", channel).ConfigureAwait(false);
BridgeConnector.Socket.Off(channel);
BridgeConnector.Socket.On<JsonElement>(channel, (args) =>
{
var arg = FormatArguments(args);
listener(arg);
});
}
private static object FormatArguments(JsonElement args)
{
var objectArray = args.Deserialize<object[]>(BoxedObjectSerializationOptions).ToList();
Debug.Assert(objectArray.Count <= 2);
if (objectArray.Count == 2)
{
return objectArray[1];
}
return null;
}
/// <summary>
/// Send a message to the renderer process synchronously via channel,
/// you can also send arbitrary arguments.
///
/// Note: Sending a synchronous message will block the whole renderer process,
/// unless you know what you are doing you should never use it.
/// </summary>
/// <param name="channel"></param>
/// <param name="listener"></param>
public void OnSync(string channel, Func<object, object> listener)
{
BridgeConnector.Socket.Emit("registerSyncIpcMainChannel", channel);
BridgeConnector.Socket.On<JsonElement>(channel, (args) =>
{
var arg = FormatArguments(args);
var result = listener(arg);
BridgeConnector.Socket.Emit(channel + "Sync", result);
});
}
/// <summary>
/// Adds a one time listener method for the event. This listener is invoked only
/// the next time a message is sent to channel, after which it is removed.
/// </summary>
/// <param name="channel">Channelname.</param>
/// <param name="listener">Callback Method.</param>
public void Once(string channel, Action<object> listener)
{
BridgeConnector.Socket.Emit("registerOnceIpcMainChannel", channel);
BridgeConnector.Socket.Once<JsonElement>(channel, (args) =>
{
var arg = FormatArguments(args);
listener(arg);
});
}
/// <summary>
/// Removes listeners of the specified channel.
/// </summary>
/// <param name="channel">Channelname.</param>
public void RemoveAllListeners(string channel)
{
BridgeConnector.Socket.Emit("removeAllListenersIpcMainChannel", channel);
}
/// <summary>
/// Send a message to the renderer process asynchronously via channel, you can also send
/// arbitrary arguments. Arguments will be serialized in JSON internally and hence
/// no functions or prototype chain will be included. The renderer process handles it by
/// listening for channel with ipcRenderer module.
/// </summary>
/// <param name="browserWindow">BrowserWindow with channel.</param>
/// <param name="channel">Channelname.</param>
/// <param name="data">Arguments data.</param>
public void Send(BrowserWindow browserWindow, string channel, params object[] data)
{
BridgeConnector.Socket.Emit("sendToIpcRenderer", browserWindow, channel, data);
}
/// <summary>
/// Send a message to the BrowserView renderer process asynchronously via channel, you can also send
/// arbitrary arguments. Arguments will be serialized in JSON internally and hence
/// no functions or prototype chain will be included. The renderer process handles it by
/// listening for channel with ipcRenderer module.
/// </summary>
/// <param name="browserView">BrowserView with channel.</param>
/// <param name="channel">Channelname.</param>
/// <param name="data">Arguments data.</param>
public void Send(BrowserView browserView, string channel, params object[] data)
{
BridgeConnector.Socket.Emit("sendToIpcRendererBrowserView", browserView.Id, channel, data);
}
}
}