Signalr: ์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜

์— ๋งŒ๋“  2012๋…„ 04์›” 19์ผ  ยท  19์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: SignalR/SignalR

์˜ค๋Š˜ ๋งŒ๋‚œ ์‚ฌ์†Œํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ๋ฉ”์†Œ๋“œ๊ฐ€ ์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ํ—ˆ์šฉํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ํ˜ธ์ถœ์ด ์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ œ์™ธํ•˜๋Š” ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค (์˜ค๋ฅ˜ : ๊ฐ’์€ null ์ผ ์ˆ˜ ์—†์Œ).

์„ฌ๊ธฐ๋Š” ์‚ฌ๋žŒ:

public void GetAll(long Id, bool DoSomething=false)

๊ณ ๊ฐ:

myHub.GetAll(12);

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์˜๋„ ํ•œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€์—†๋Š” ํ˜ธ์ถœ์ด ์žˆ๋Š”๋ฐ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ๊นจ์ง€ ์•Š๊ณ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋Š” ํ˜„์žฌ ์ธ์ˆ˜์—†์ด ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— System.IO.InvalidDataException : Invocation์€ 0 ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ target์€ 1 ๊ฐœ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

null์„ ์ „๋‹ฌํ•˜๋„๋ก ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค .๐Ÿ˜ฆ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• : ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์ „๋‹ฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์›๋ž˜ ์ด๋ฆ„์œผ๋กœ ๋‹ค์‹œ ์ „๋‹ฌ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ์ƒˆ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์‹ค๋ง ๐Ÿ‘Ž

๋ชจ๋“  19 ๋Œ“๊ธ€

๋ฉ”์„œ๋“œ ํ•ด๊ฒฐ์„ ๋” ์Šค๋งˆํŠธํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™•์‹คํžˆ ์ข‹์€ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ ๋‹น์‹œ์—๋Š” ๊ธฐ๋ณธ ๋™์  ํ—ˆ๋ธŒ ๊ตฌํ˜„์„ ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ํ‘ธ์‹œํ•˜๋„๋ก ๋˜๋Œ ๋ ธ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ ํ•˜๋ฉด ...
ํ˜„์žฌ ๊ตฌํ˜„์—์„œ๋Š” ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋กœ๋“œ ์ง€์›์„ ์ถ”๊ฐ€ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช…๋ช… ๋œ ๋งค๊ฐœ ๋ณ€์ˆ˜ ํ™•์ธ๋„ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์‹ค์ œ๋กœ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ„์— ์ „๋‹ฌ๋˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ผ๋ถ€ ์ˆ˜์ •์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค (๊ฐ’ ๋Œ€์‹  ํ‚ค-๊ฐ’ ์Œ ์ „๋‹ฌ). ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋‹ˆ?

Nullable ๋งค๊ฐœ ๋ณ€์ˆ˜์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๊นŒ? 3 ๊ฐœ์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€์žˆ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ ์ค‘ ๋งˆ์ง€๋ง‰์€ nullable int (int?)์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ null๋กœ ์„ค์ •ํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ฐ’์€ null ์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
๋งค๊ฐœ ๋ณ€์ˆ˜ ์ด๋ฆ„ : o

Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull (Object value, String parameterName)
Newtonsoft.Json.Linq.JToken.FromObjectInternal (Object o, JsonSerializer jsonSerializer)์—์„œ
Newtonsoft.Json.Linq.JToken.FromObject (Object o, JsonSerializer jsonSerializer)
Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke T์—์„œ
GeoTag.App.Core.Services.SignalRClientService์—์„œd__9.MoveNext ()

์„œ๋ฒ„์—์„œ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ v3 ํ›„๋ณด๋กœ ์ƒˆ ์ €์žฅ์†Œ๋กœ ์˜ฎ๊ธธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@JasonBSteele-์˜ค๋žœ๋งŒ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์–ธ๊ธ‰ํ•˜์‹  ๋ฌธ์ œ๋Š” ๋ฐฉ๊ธˆ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์˜ ์ƒํƒœ์— ๋Œ€ํ•ด ํ˜ผ๋ž€ ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. SignalR ๋ฆด๋ฆฌ์Šค์—์„œ ์ˆ˜์ • ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

@paulirwin No

...

์ˆ˜์ • ์‚ฌํ•ญ์€ 7 ์›”์— ์ถœ์‹œ ๋œ 2.2.1์— ์žˆ์Šต๋‹ˆ๋‹ค (https://github.com/SignalR/SignalR/releases/tag/2.2.1).

๋‚˜๋Š” ์–ด์ œ ๋งŒ๋‚œ ๊ฒƒ์„ ๋‹ค์‹œ ํ…Œ์ŠคํŠธํ–ˆ์œผ๋ฉฐ ๋‹ค์Œ์€ ๋‚ด ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.
ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ˜ธ์ถœ ํ•  ํ—ˆ๋ธŒ ๋ฉ”์„œ๋“œ

public async Task EpicMethod( int? daysTillNETStandard20 ) {}

.NET ํด๋ผ์ด์–ธํŠธ ์„œ๋ฒ„ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ๋„ :

1. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null).ConfigureAwait(false);

System.ArgumentNullException: Value cannot be null.
Parameter name: args
   at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke[TResult,TProgress](String method, Action`1 onProgress, Object[] args)
   at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke(String method, Object[] args)

2. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null, null).ConfigureAwait(false);

System.InvalidOperationException: 'EpicMethod' method could not be resolved. Potential candidates are: 
EpicMethod(daysTillNETStandard20:Nullable`1):Task

3. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null, new object[] {}).ConfigureAwait(false);

System.InvalidOperationException: 'EpicMethod' method could not be resolved. Potential candidates are: 
EpicMethod(daysTillNETStandard20:Nullable`1):Task
4. await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), null, new object[] {null}).ConfigureAwait(false);
System.InvalidOperationException: 'EpicMethod' method could not be resolved. Potential candidates are: 
EpicMethod(daysTillNETStandard20:Nullable`1):Task

๊ทธ๋ž˜์„œ ์ง€๊ธˆ์€ ํ—ˆ๋ธŒ ๋ฉ”์„œ๋“œ์—์„œ null ํ—ˆ์šฉ ์—ฌ๋ถ€๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ 0์„ ์ „๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฐพ์€ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ๋‹ค์‹œ ์—ฌ๋Š” ์ค‘ ...

๋‚˜๋„์ด ๋ฌธ์ œ๊ฐ€์žˆ๋‹ค. ํ•ด๊ฒฐ ๋ ๊นŒ์š”?

null ์„ Nullable<T> ๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š๋Š” ๋ฐ”์ธ๋”์˜ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ์กฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ ๋””์ž์ธ์— ์˜ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. null ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ๋กœ ๊ฐ์ฒด ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•. ๋‹น์‹ ์˜ ์˜ˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ ‡๊ฒŒ
await _serviceRequestHubProxy.Invoke(nameof(ISomethingOnServerSide.EpicMethod), new object[] {null}).ConfigureAwait(false);

๋‹น์‹ ์ดํ•˜๊ณ ์žˆ๋Š” ์ผ์€ ๋งค๊ฐœ ๋ณ€์ˆ˜ ํ•ด์„๊ธฐ๊ฐ€ null ๊ฐ’์„ params ๋ฐฐ์—ด์— ์ „๋‹ฌํ•˜๋Š” ๋Œ€์‹  null๋กœ ์‚ฌ์šฉํ•˜๋Š” params ๋ฐฐ์—ด์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋ฒ„์ „์—์„œ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์–ด์•ผํ•ฉ๋‹ˆ๊นŒ? ๋ฐœํ–‰์ผ์ด 5 ๋…„ ์ „ ์ด์—ˆ์œผ๋ฏ€๋กœ ์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

@AlameerAshraf- ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” ์ž‘์—…์„ ์ •ํ™•ํ•˜๊ฒŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š”์ด ์˜์—ญ์—์„œ ์–ด๋–ค ๊ฒƒ๋„ ๋ณ€๊ฒฝํ•  ๊ณ„ํš์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์˜๋„ ํ•œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€์—†๋Š” ํ˜ธ์ถœ์ด ์žˆ๋Š”๋ฐ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ๊นจ์ง€ ์•Š๊ณ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋Š” ํ˜„์žฌ ์ธ์ˆ˜์—†์ด ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— System.IO.InvalidDataException : Invocation์€ 0 ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ target์€ 1 ๊ฐœ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

null์„ ์ „๋‹ฌํ•˜๋„๋ก ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค .๐Ÿ˜ฆ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• : ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์ „๋‹ฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์›๋ž˜ ์ด๋ฆ„์œผ๋กœ ๋‹ค์‹œ ์ „๋‹ฌ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ์ƒˆ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์‹ค๋ง ๐Ÿ‘Ž

์„ ํƒ์  ๋ฉ”์„œ๋“œ ๋งค๊ฐœ ๋ณ€์ˆ˜์™€ ์˜ค๋ฒ„๋กœ๋”ฉ์ด ์ง€์›๋˜์–ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. SignalR์„ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ๊ณผ ๋ฐ˜ ์ง๊ด€์  ์ธ ๋ฐฉ๋ฒ•์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ์‹ค์ œ๋กœ ๊ธฐํ•œ์ด ์ง€๋‚œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ 2020 ๋…„์— ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋กœ๋”ฉ์ด ์ž‘๋™ํ•˜์ง€๋งŒ ์„ ํƒ์  ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ๋งค๊ฐœ ๋ณ€์ˆ˜ํ™”๋˜์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ๋ฅผ ๋‹จ์ˆœํžˆ ๋งค๊ฐœ ๋ณ€์ˆ˜ํ™”๋˜์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์—ฌ์ „ํžˆ ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰