mirror of https://github.com/grpc/grpc-dotnet.git
Compare commits
684 Commits
v2.26.0-pr
...
master
Author | SHA1 | Date |
---|---|---|
|
4ee90d83ce | |
|
fc1f6db9fd | |
|
f31cd71abf | |
|
0045d7d123 | |
|
d07efb500c | |
|
9764314a84 | |
|
3bd324e325 | |
|
add543720d | |
|
44b243fb00 | |
|
66df240b07 | |
|
1cb0fdb29a | |
|
85787a7ce2 | |
|
d170b24e9d | |
|
b1af190d8c | |
|
6f03f0e0b5 | |
|
30553b5624 | |
|
2aed7b5ef3 | |
|
06cd2a9f7a | |
|
5816e69828 | |
|
147a4647ad | |
|
852a118c7b | |
|
60d9d2ce15 | |
|
a2f7d06e02 | |
|
c9d26719e8 | |
|
b7af033360 | |
|
6a3c9774f6 | |
|
cacf59d942 | |
|
be98a74f68 | |
|
42593dde65 | |
|
651a0cb64a | |
|
3bf19a113c | |
|
b6cfbd05e9 | |
|
5a58c24efc | |
|
dacb7b41ea | |
|
1732f28dc6 | |
|
5fffc489f7 | |
|
b88713e83f | |
|
0f2ffdc03e | |
|
490894cded | |
|
df3d8dc996 | |
|
b1df3e4c76 | |
|
de9a82fe8e | |
|
3ed9fb9f31 | |
|
5322d6b813 | |
|
439a3b80b5 | |
|
b3429b9061 | |
|
30255261ad | |
|
bf41c89ace | |
|
e9cc7e1579 | |
|
26227c3e7a | |
|
dd4adce098 | |
|
c397bc7804 | |
|
74ee5f0ebf | |
|
a732f517ea | |
|
a156ca9955 | |
|
cd875d9097 | |
|
540e87bf70 | |
|
b34d553e44 | |
|
35b63dad57 | |
|
6448783899 | |
|
aab5b2b798 | |
|
4623318100 | |
|
1416340c85 | |
|
64f6a0958a | |
|
434a5ba26b | |
|
5e6821cbe3 | |
|
b57c87f2a9 | |
|
775d1fba1c | |
|
0ea0112ec8 | |
|
84a4fcb697 | |
|
bca64852ba | |
|
ef1f0d209c | |
|
9ad10a9196 | |
|
4b6ecea955 | |
|
989420e709 | |
|
c80f4594d0 | |
|
63914f2653 | |
|
8199f66422 | |
|
2d9df5892c | |
|
c9c902c8da | |
|
2a36215697 | |
|
9cd97cebca | |
|
c04d01a0ac | |
|
add886e45b | |
|
f2709f1bf5 | |
|
a4d83f6d75 | |
|
a51fec8ff1 | |
|
874cd11637 | |
|
933023b6f8 | |
|
f29d927f42 | |
|
098dca892a | |
|
787faa64c7 | |
|
da2038226c | |
|
7cd4bc2447 | |
|
6d1ea08ce3 | |
|
1a8435477f | |
|
7f5b4574aa | |
|
3103c6937f | |
|
0cad7497d0 | |
|
4b0b3589db | |
|
e5c9528912 | |
|
abaaf4415c | |
|
934bcec442 | |
|
f075c79e18 | |
|
87cce280d7 | |
|
998a8cc63b | |
|
1625f89427 | |
|
2bbb977dd2 | |
|
ca9b756d73 | |
|
4a60f414a1 | |
|
e5afb085e0 | |
|
5e505b017a | |
|
8d33f094d2 | |
|
e52049a94d | |
|
51ad5ab757 | |
|
3c4abbada1 | |
|
91be3925c1 | |
|
683fbdfa5c | |
|
bad41ff570 | |
|
207e8066f3 | |
|
97f6fbd3fe | |
|
7e62218646 | |
|
46480fca2f | |
|
40a26c9877 | |
|
246c43d457 | |
|
91130a7c89 | |
|
3f90844449 | |
|
b50e46f851 | |
|
311f8784c6 | |
|
b421751176 | |
|
41f67ad900 | |
|
a9e810c3df | |
|
6429ae2f57 | |
|
3db1683820 | |
|
01049834be | |
|
ca3f2b9d51 | |
|
aa2bc14f5e | |
|
a970fec15d | |
|
89dd217257 | |
|
2b1da779bf | |
|
6ca24ef45b | |
|
5a8e2baf37 | |
|
854e0fd3d0 | |
|
22a9549897 | |
|
870bf8443f | |
|
89e6611d2d | |
|
a61e11f1e0 | |
|
d49fbe40d5 | |
|
4367702140 | |
|
d305ee4bc6 | |
|
19e059f073 | |
|
cec98b28d5 | |
|
6420a8cf9f | |
|
6a4bca703a | |
|
a2d005c86b | |
|
1d1234064c | |
|
0ab3ada34a | |
|
bff852c7f1 | |
|
e0677497de | |
|
03d9b01fbb | |
|
6307ca7ead | |
|
8275c602a9 | |
|
1e32a39efa | |
|
5751c4dd3e | |
|
067bfc8fd8 | |
|
d884b50a27 | |
|
85f34398df | |
|
16e01b9369 | |
|
42cc09eb8f | |
|
83d12ea1cb | |
|
99604e5a9a | |
|
bc6da06036 | |
|
5a2887497e | |
|
266be407f6 | |
|
c72ada62e6 | |
|
2be676ad3b | |
|
73c726bf4e | |
|
697f3492f2 | |
|
ff1a07b90c | |
|
6bc44e97d7 | |
|
f9a00bc490 | |
|
2dc971e013 | |
|
1412c31924 | |
|
a95f0f08e9 | |
|
7786079da6 | |
|
38738af700 | |
|
9427a740a4 | |
|
b83aece3cf | |
|
8af472314e | |
|
94a8167500 | |
|
e270f816b4 | |
|
6bf44820a2 | |
|
0998624ce9 | |
|
54d7f29913 | |
|
b82c0c7354 | |
|
fb315ca62b | |
|
c24dfebe22 | |
|
95cf7fc928 | |
|
f056e80af0 | |
|
23cd81fbdb | |
|
cfb839bd7c | |
|
c2274eb07d | |
|
a456d47405 | |
|
84718236a9 | |
|
0b365bf463 | |
|
0f9300c439 | |
|
ad54bc69ed | |
|
fc4d087d63 | |
|
674758e4d3 | |
|
2cdbf1c308 | |
|
4bf9312123 | |
|
0a26b0cad6 | |
|
b81a92d17b | |
|
4c07771aea | |
|
948be08b08 | |
|
96ea3836b4 | |
|
33f6ae36c9 | |
|
b92eb109f1 | |
|
f7e186f18e | |
|
2ea8177bc8 | |
|
3a356b3719 | |
|
ff89215fbc | |
|
9ab0b4508f | |
|
d2c8146302 | |
|
d2c5a7a5b9 | |
|
8474b75b41 | |
|
d4704d8f44 | |
|
11e7cfa3da | |
|
1a9cf64a72 | |
|
5a0b1eec01 | |
|
17ef8fdbe5 | |
|
cb88ac90ca | |
|
c72d1a82a5 | |
|
3ae11a4cef | |
|
a98c6218e0 | |
|
664f5559f6 | |
|
e28a43ffed | |
|
bb406e8bfa | |
|
80e2fabcf9 | |
|
23047e0d49 | |
|
91ac7754f2 | |
|
faf6234b3d | |
|
25f7b137d7 | |
|
97b7f6d4d7 | |
|
0828c036bb | |
|
6c48114e67 | |
|
7154cb470d | |
|
4c2e66ed85 | |
|
45dd5d171c | |
|
947a24aefe | |
|
22ac73b110 | |
|
e7fd8004c0 | |
|
e86adbf656 | |
|
3617dc1c78 | |
|
cb02fb7e8f | |
|
ad67dc8d27 | |
|
456098bcfe | |
|
371d74fc95 | |
|
0f5c5782e3 | |
|
0ab5e2c509 | |
|
9950fd717b | |
|
9852674a88 | |
|
54fa142547 | |
|
195e1c0922 | |
|
7980069be0 | |
|
884d918e3c | |
|
792eb3b570 | |
|
8ae9c96c18 | |
|
937869c130 | |
|
2116d1efce | |
|
7bfd8e385a | |
|
922d314630 | |
|
0551be8b6b | |
|
1d7f98834c | |
|
4f06b601aa | |
|
77ae8af69c | |
|
d250e28e70 | |
|
4e9077c9ae | |
|
3934c6c702 | |
|
a3717a3587 | |
|
ca40f28ab7 | |
|
5ff18048d1 | |
|
9d0919fe05 | |
|
c319c44ec8 | |
|
25c2b9115a | |
|
b77a58963b | |
|
a984c6d55c | |
|
7a6e2fe207 | |
|
5f587ae2e0 | |
|
6507e9bf37 | |
|
2923260a0c | |
|
de472b186c | |
|
d9755701cf | |
|
cbb0836991 | |
|
78d11d14ad | |
|
6bbbf36277 | |
|
58cd9dc9cb | |
|
543c363c5e | |
|
2c175e01ca | |
|
f850d75d85 | |
|
0ddbb72c3e | |
|
c0779fc83f | |
|
fedf5ab017 | |
|
1f5186e6a7 | |
|
4b10c6c7bf | |
|
e616db6506 | |
|
9e073cd6e6 | |
|
52c6154435 | |
|
be641b6ffe | |
|
248c580a7c | |
|
7cf2aa077c | |
|
d7cf5a83dd | |
|
3f63a9ac94 | |
|
3ac2881a7a | |
|
c46859372f | |
|
38845e5523 | |
|
819dea5af6 | |
|
7d2c3c169a | |
|
7d013e0121 | |
|
a2c907f69d | |
|
24245fd677 | |
|
5982753253 | |
|
770947bd25 | |
|
c9b8aa7dec | |
|
af4a858335 | |
|
713935fbf7 | |
|
d2cc71676a | |
|
0ebfff1e83 | |
|
db0dafc78a | |
|
2bb25cab6c | |
|
197b43bbf7 | |
|
d02f71a759 | |
|
70dd439625 | |
|
4728d65414 | |
|
d45c350307 | |
|
737f712afe | |
|
bfe312a3ba | |
|
295165518d | |
|
87680d504a | |
|
bbbfdc0f02 | |
|
9f83f9b5ef | |
|
6d3e6af1e1 | |
|
f238855fcb | |
|
d0272085d9 | |
|
ea5f673c10 | |
|
1cc747cfbf | |
|
0551d6aa2e | |
|
b401c2c7e3 | |
|
05c25a3c5e | |
|
502648751e | |
|
d4ee8babcd | |
|
b001e02756 | |
|
41b8e2e76a | |
|
f47ac6bfb8 | |
|
f01df42b02 | |
|
7057da7ae7 | |
|
15d027bc93 | |
|
5c206d0e9f | |
|
b3e8ba64ee | |
|
85b92220ec | |
|
5641257032 | |
|
a007d43bc7 | |
|
bdcd0eaf12 | |
|
11d7151e7f | |
|
fa546befa2 | |
|
21a1412b87 | |
|
aed01fe9f4 | |
|
137e377efb | |
|
306abc2979 | |
|
915b15de18 | |
|
1d60a7c02d | |
|
282fa2af8f | |
|
82f89083ed | |
|
3a355c21c7 | |
|
1d18ed324b | |
|
7b95a53cf2 | |
|
3add750544 | |
|
a08e7372ff | |
|
da6dcc5ca2 | |
|
6cc34ee5e7 | |
|
257da89bf1 | |
|
ea7a00e7e2 | |
|
687fbb44a0 | |
|
1215046255 | |
|
6d4892c487 | |
|
2ff1f4ef8e | |
|
eb813a798a | |
|
518a6362ba | |
|
a04684ab23 | |
|
a23602367d | |
|
1ac3a3f3be | |
|
9c936f3ca5 | |
|
6acecf4ad4 | |
|
3ebcc938a9 | |
|
8fa8389812 | |
|
bce585246d | |
|
7d081d7c26 | |
|
520c57415e | |
|
d5626ab20b | |
|
d2035de5f6 | |
|
fb42fc0c8a | |
|
16a1bb4ca4 | |
|
78bf205a90 | |
|
747088e5b8 | |
|
b9cb8806ae | |
|
0d5a300154 | |
|
868adfe377 | |
|
f5e4ad7384 | |
|
7ef184f3c4 | |
|
5d447fdc8e | |
|
dce1ef72d8 | |
|
202985251b | |
|
e48a0364d5 | |
|
00f7601709 | |
|
763d3b99a3 | |
|
a7c6c47bc4 | |
|
b1e7b44387 | |
|
b04688b437 | |
|
530eb1c25c | |
|
82dec0ff51 | |
|
a9b0064a66 | |
|
d5682d4823 | |
|
afe2100cda | |
|
c85ca5c432 | |
|
48eb2e9074 | |
|
f777808fa1 | |
|
cb2f9d7826 | |
|
17b2beb9b7 | |
|
b63993f40d | |
|
056e386ad9 | |
|
c1d3bbfccd | |
|
ac3b3f4309 | |
|
3469513fe7 | |
|
5f762ae977 | |
|
8666a11362 | |
|
0f26bd7b2f | |
|
7c35727de4 | |
|
a01ea842a7 | |
|
bb9284fb62 | |
|
094532f0fb | |
|
7be660d629 | |
|
c804021ac3 | |
|
15158af86d | |
|
95ea1dcb1b | |
|
e3a2c06639 | |
|
36df3c2e31 | |
|
a6eccf0dc3 | |
|
11f0958d12 | |
|
1cd34bd832 | |
|
f77622b3bd | |
|
f552a4982f | |
|
d585f36132 | |
|
420ca57ac2 | |
|
e920c52048 | |
|
8db4604542 | |
|
8b30ef9c7a | |
|
a1389a0811 | |
|
bf26e0377a | |
|
6920e2abd0 | |
|
f54a118569 | |
|
5bb5f48fc4 | |
|
31009f6de1 | |
|
5d223d540e | |
|
e0b839290f | |
|
560e141e68 | |
|
4c410dcc39 | |
|
650aaa110f | |
|
2ab0587190 | |
|
9f72e70c6a | |
|
ebf7bbd9b2 | |
|
bb14b9b2ea | |
|
85883a2d4b | |
|
2844af7c2c | |
|
7f341664d6 | |
|
78306e4723 | |
|
57a7ad5339 | |
|
7e3f2c3115 | |
|
6fd69504c7 | |
|
4f61419d80 | |
|
45ab5036e7 | |
|
b93d87eff1 | |
|
b95400a20f | |
|
ab79d7fc40 | |
|
b8a2408f18 | |
|
250331e390 | |
|
761bfe8f71 | |
|
be36d78d79 | |
|
4b4a7bd2b5 | |
|
37653639d6 | |
|
978200abd5 | |
|
5c7cf6cf33 | |
|
37660f5de4 | |
|
a72397cebb | |
|
08024e350d | |
|
3c675bed8f | |
|
927c0e5d72 | |
|
538e3720a6 | |
|
9c3385ad84 | |
|
4a8a120317 | |
|
a3e67446a2 | |
|
822c36fea4 | |
|
76ae64d3b0 | |
|
d8d982b291 | |
|
ec6de5c047 | |
|
e34cef6c64 | |
|
7d6683e3b3 | |
|
ab2efbaed1 | |
|
df29d5274c | |
|
291ddf395c | |
|
543ee70bc8 | |
|
4da20fba32 | |
|
bbf8ffe982 | |
|
ac2523fc2a | |
|
04b0a1cdb7 | |
|
c637a4e9f1 | |
|
dfd2cb3f96 | |
|
850f455753 | |
|
cd2e76860c | |
|
a435b71956 | |
|
123ae72fb5 | |
|
dd4dca5b7b | |
|
e7e779f35f | |
|
922b8dfd39 | |
|
13a4bf1b2d | |
|
c48ae4442f | |
|
bf3b057e32 | |
|
3807a8cb58 | |
|
e37e2f13a1 | |
|
874cb5535e | |
|
e36e1218e9 | |
|
96c06f45e7 | |
|
be778112dc | |
|
4827aea48d | |
|
00d6a0b4a8 | |
|
27257a7c3b | |
|
3518cd7570 | |
|
a2918b07a2 | |
|
5395000b37 | |
|
86f4600121 | |
|
f418e5d5f7 | |
|
11a7146c9e | |
|
637afdbec6 | |
|
59062ec54d | |
|
7fe4595de9 | |
|
139040e840 | |
|
0a37300796 | |
|
84f6a3e7d0 | |
|
a76308fd2b | |
|
47b7506e1f | |
|
1e82c56974 | |
|
cc7b97f6da | |
|
b10480cbe0 | |
|
fdb96193ba | |
|
a9827e5ccc | |
|
55cde44349 | |
|
af709ddf42 | |
|
5faaabef72 | |
|
4bf32368ee | |
|
ef77760676 | |
|
6df196c110 | |
|
4c92b23cfb | |
|
c42358b2c3 | |
|
1b44bef567 | |
|
49fc4f1841 | |
|
634fda1fec | |
|
797619b329 | |
|
aca0a8def5 | |
|
75c5cbb082 | |
|
e911dac2e5 | |
|
39c2dcd78e | |
|
6b65f9b2ad | |
|
59ac331075 | |
|
27cf289089 | |
|
02883fb00d | |
|
08a0a558c7 | |
|
9c294e0394 | |
|
b9f862170a | |
|
7e8b6e85f1 | |
|
4daaf07a26 | |
|
e02fd189d1 | |
|
ba05ea11b8 | |
|
e1669ed6f2 | |
|
8251675415 | |
|
ff32e56713 | |
|
64efb1cd68 | |
|
f89cfc2fa9 | |
|
283098b2d5 | |
|
9b759a54d0 | |
|
241b21df05 | |
|
1344beb663 | |
|
c2cf53641f | |
|
074b17a573 | |
|
90c0ecc41c | |
|
32df65a6c3 | |
|
5de614014d | |
|
103105e75f | |
|
9bc4d27d39 | |
|
41618a497b | |
|
90609adec0 | |
|
1b3588ca21 | |
|
97af9b2fa5 | |
|
035c791b10 | |
|
38ea7e8441 | |
|
54add4f70f | |
|
4d7cad8e00 | |
|
f182c41f1f | |
|
52165289fe | |
|
cf09aafced | |
|
1df26fe32d | |
|
bba2e5d385 | |
|
f99787e28f | |
|
6f452e10b7 | |
|
1ca4245af8 | |
|
70d9728aa7 | |
|
305cb17e2a | |
|
3ce9b10452 | |
|
95159e54c7 | |
|
c6b8f6c706 | |
|
58b2e1c9b3 | |
|
cb7c70e2ef | |
|
a5d970b5f2 | |
|
554ea26113 | |
|
262de5b28c | |
|
afc2b21761 | |
|
fced036711 | |
|
dfb34ae672 | |
|
2c2b8adf43 | |
|
04bbe4fc59 | |
|
57fa08534b | |
|
03778703f3 | |
|
95c99074b0 | |
|
799a8a1f66 | |
|
5dd0eef830 | |
|
5c6080a204 | |
|
adf4deb6ed | |
|
3a9b23de55 | |
|
b26695aceb | |
|
a656d7abb6 | |
|
cc00b55b06 | |
|
0b5320af97 | |
|
663b228bdb | |
|
76abb53787 | |
|
4864460865 | |
|
24b6b0c2ad | |
|
f98933ce04 | |
|
af93d32591 | |
|
1159126138 | |
|
2cb89bf446 | |
|
3ec2aa8c60 | |
|
db7d128f59 | |
|
344c4adc93 | |
|
9390e16e8d | |
|
d1b2b6496b | |
|
e032d5046c | |
|
41f591d235 | |
|
7c01479a07 | |
|
1de1aaf3bb | |
|
a6f1e476a7 | |
|
a1bb10d4a9 | |
|
793bb6564c | |
|
93d1a3872e | |
|
de6144f3c8 | |
|
b2845043e8 | |
|
176fb17794 | |
|
8c0f682173 | |
|
d00da897cc | |
|
0da0662e45 | |
|
0d35b5a60d | |
|
63d5ac2acc | |
|
444ff1b0ff | |
|
8283efe58e | |
|
249dabab70 | |
|
bee59db0be | |
|
36e42811e7 | |
|
25018df77e | |
|
ae35982440 | |
|
263e54ffdb | |
|
89a95c3369 | |
|
dd72d6a38a | |
|
1e8e31b15d | |
|
afd37e4d0a | |
|
dcf6f339ca | |
|
60c8feb989 | |
|
7d9b3406a2 |
|
@ -0,0 +1,3 @@
|
|||
**/bin
|
||||
**/obj
|
||||
.vs
|
|
@ -0,0 +1,406 @@
|
|||
; EditorConfig to support per-solution formatting.
|
||||
; Use the EditorConfig VS add-in to make this work.
|
||||
; http://editorconfig.org/
|
||||
;
|
||||
; Here are some resources for what's supported for .NET/C#
|
||||
; https://kent-boogaart.com/blog/editorconfig-reference-for-c-developers
|
||||
; https://learn.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
|
||||
;
|
||||
; Be **careful** editing this because some of the rules don't support adding a severity level
|
||||
; For instance if you change to `dotnet_sort_system_directives_first = true:warning` (adding `:warning`)
|
||||
; then the rule will be silently ignored.
|
||||
|
||||
; This is the default for the codeline.
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.cs]
|
||||
indent_size = 4
|
||||
dotnet_sort_system_directives_first = true
|
||||
|
||||
# Don't use this. qualifier
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
|
||||
# use int x = .. over Int32
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
|
||||
# use int.MaxValue over Int32.MaxValue
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
# Require var all the time.
|
||||
csharp_style_var_for_built_in_types = true:suggestion
|
||||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
|
||||
# Disallow throw expressions.
|
||||
csharp_style_throw_expression = false:suggestion
|
||||
|
||||
# Newline settings
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
|
||||
# Namespace settings
|
||||
csharp_style_namespace_declarations = file_scoped
|
||||
|
||||
# Brace settings
|
||||
csharp_prefer_braces = true # Prefer curly braces even for one line of code
|
||||
|
||||
[*.{xml,config,*proj,nuspec,props,resx,targets,yml,tasks}]
|
||||
indent_size = 2
|
||||
|
||||
# Xml config files
|
||||
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
|
||||
indent_size = 2
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
[*.{ps1,psm1}]
|
||||
indent_size = 4
|
||||
|
||||
[*.sh]
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
|
||||
[*.{razor,cshtml}]
|
||||
charset = utf-8-bom
|
||||
|
||||
[*.{cs,vb}]
|
||||
|
||||
# SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time
|
||||
dotnet_diagnostic.SYSLIB1054.severity = warning
|
||||
|
||||
# CA1018: Mark attributes with AttributeUsageAttribute
|
||||
dotnet_diagnostic.CA1018.severity = warning
|
||||
|
||||
# CA1047: Do not declare protected member in sealed type
|
||||
dotnet_diagnostic.CA1047.severity = warning
|
||||
|
||||
# CA1305: Specify IFormatProvider
|
||||
dotnet_diagnostic.CA1305.severity = warning
|
||||
|
||||
# CA1507: Use nameof to express symbol names
|
||||
dotnet_diagnostic.CA1507.severity = warning
|
||||
|
||||
# CA1510: Use ArgumentNullException throw helper
|
||||
dotnet_diagnostic.CA1510.severity = warning
|
||||
|
||||
# CA1511: Use ArgumentException throw helper
|
||||
dotnet_diagnostic.CA1511.severity = warning
|
||||
|
||||
# CA1512: Use ArgumentOutOfRangeException throw helper
|
||||
dotnet_diagnostic.CA1512.severity = warning
|
||||
|
||||
# CA1513: Use ObjectDisposedException throw helper
|
||||
dotnet_diagnostic.CA1513.severity = warning
|
||||
|
||||
# CA1725: Parameter names should match base declaration
|
||||
dotnet_diagnostic.CA1725.severity = suggestion
|
||||
|
||||
# CA1802: Use literals where appropriate
|
||||
dotnet_diagnostic.CA1802.severity = warning
|
||||
|
||||
# CA1805: Do not initialize unnecessarily
|
||||
dotnet_diagnostic.CA1805.severity = warning
|
||||
|
||||
# CA1810: Do not initialize unnecessarily
|
||||
dotnet_diagnostic.CA1810.severity = warning
|
||||
|
||||
# CA1821: Remove empty Finalizers
|
||||
dotnet_diagnostic.CA1821.severity = warning
|
||||
|
||||
# CA1822: Make member static
|
||||
dotnet_diagnostic.CA1822.severity = warning
|
||||
dotnet_code_quality.CA1822.api_surface = private, internal
|
||||
|
||||
# CA1823: Avoid unused private fields
|
||||
dotnet_diagnostic.CA1823.severity = warning
|
||||
|
||||
# CA1825: Avoid zero-length array allocations
|
||||
dotnet_diagnostic.CA1825.severity = warning
|
||||
|
||||
# CA1826: Do not use Enumerable methods on indexable collections. Instead use the collection directly
|
||||
dotnet_diagnostic.CA1826.severity = warning
|
||||
|
||||
# CA1827: Do not use Count() or LongCount() when Any() can be used
|
||||
dotnet_diagnostic.CA1827.severity = warning
|
||||
|
||||
# CA1828: Do not use CountAsync() or LongCountAsync() when AnyAsync() can be used
|
||||
dotnet_diagnostic.CA1828.severity = warning
|
||||
|
||||
# CA1829: Use Length/Count property instead of Count() when available
|
||||
dotnet_diagnostic.CA1829.severity = warning
|
||||
|
||||
# CA1830: Prefer strongly-typed Append and Insert method overloads on StringBuilder
|
||||
dotnet_diagnostic.CA1830.severity = warning
|
||||
|
||||
# CA1831: Use AsSpan or AsMemory instead of Range-based indexers when appropriate
|
||||
# CA1832: Use AsSpan or AsMemory instead of Range-based indexers when appropriate
|
||||
# CA1833: Use AsSpan or AsMemory instead of Range-based indexers when appropriate
|
||||
dotnet_diagnostic.CA1831.severity = warning
|
||||
dotnet_diagnostic.CA1832.severity = warning
|
||||
dotnet_diagnostic.CA1833.severity = warning
|
||||
|
||||
# CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
||||
dotnet_diagnostic.CA1834.severity = warning
|
||||
|
||||
# CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
|
||||
dotnet_diagnostic.CA1835.severity = warning
|
||||
|
||||
# CA1836: Prefer IsEmpty over Count
|
||||
dotnet_diagnostic.CA1836.severity = warning
|
||||
|
||||
# CA1837: Use 'Environment.ProcessId'
|
||||
dotnet_diagnostic.CA1837.severity = warning
|
||||
|
||||
# CA1838: Avoid 'StringBuilder' parameters for P/Invokes
|
||||
dotnet_diagnostic.CA1838.severity = warning
|
||||
|
||||
# CA1839: Use 'Environment.ProcessPath'
|
||||
dotnet_diagnostic.CA1839.severity = warning
|
||||
|
||||
# CA1840: Use 'Environment.CurrentManagedThreadId'
|
||||
dotnet_diagnostic.CA1840.severity = warning
|
||||
|
||||
# CA1841: Prefer Dictionary.Contains methods
|
||||
dotnet_diagnostic.CA1841.severity = warning
|
||||
|
||||
# CA1842: Do not use 'WhenAll' with a single task
|
||||
dotnet_diagnostic.CA1842.severity = warning
|
||||
|
||||
# CA1843: Do not use 'WaitAll' with a single task
|
||||
dotnet_diagnostic.CA1843.severity = warning
|
||||
|
||||
# CA1844: Provide memory-based overrides of async methods when subclassing 'Stream'
|
||||
dotnet_diagnostic.CA1844.severity = warning
|
||||
|
||||
# CA1845: Use span-based 'string.Concat'
|
||||
dotnet_diagnostic.CA1845.severity = warning
|
||||
|
||||
# CA1846: Prefer AsSpan over Substring
|
||||
dotnet_diagnostic.CA1846.severity = warning
|
||||
|
||||
# CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
|
||||
dotnet_diagnostic.CA1847.severity = warning
|
||||
|
||||
# CA1852: Seal internal types
|
||||
dotnet_diagnostic.CA1852.severity = warning
|
||||
|
||||
# CA1854: Prefer the IDictionary.TryGetValue(TKey, out TValue) method
|
||||
dotnet_diagnostic.CA1854.severity = warning
|
||||
|
||||
# CA1855: Prefer 'Clear' over 'Fill'
|
||||
dotnet_diagnostic.CA1855.severity = warning
|
||||
|
||||
# CA1856: Incorrect usage of ConstantExpected attribute
|
||||
dotnet_diagnostic.CA1856.severity = error
|
||||
|
||||
# CA1857: A constant is expected for the parameter
|
||||
dotnet_diagnostic.CA1857.severity = warning
|
||||
|
||||
# CA1858: Use 'StartsWith' instead of 'IndexOf'
|
||||
dotnet_diagnostic.CA1858.severity = warning
|
||||
|
||||
# CA2007: Consider calling ConfigureAwait on the awaited task
|
||||
dotnet_diagnostic.CA2007.severity = warning
|
||||
|
||||
# CA2008: Do not create tasks without passing a TaskScheduler
|
||||
dotnet_diagnostic.CA2008.severity = warning
|
||||
|
||||
# CA2009: Do not call ToImmutableCollection on an ImmutableCollection value
|
||||
dotnet_diagnostic.CA2009.severity = warning
|
||||
|
||||
# CA2011: Avoid infinite recursion
|
||||
dotnet_diagnostic.CA2011.severity = warning
|
||||
|
||||
# CA2012: Use ValueTask correctly
|
||||
dotnet_diagnostic.CA2012.severity = warning
|
||||
|
||||
# CA2013: Do not use ReferenceEquals with value types
|
||||
dotnet_diagnostic.CA2013.severity = warning
|
||||
|
||||
# CA2014: Do not use stackalloc in loops.
|
||||
dotnet_diagnostic.CA2014.severity = warning
|
||||
|
||||
# CA2016: Forward the 'CancellationToken' parameter to methods that take one
|
||||
dotnet_diagnostic.CA2016.severity = warning
|
||||
|
||||
# CA2200: Rethrow to preserve stack details
|
||||
dotnet_diagnostic.CA2200.severity = warning
|
||||
|
||||
# CA2208: Instantiate argument exceptions correctly
|
||||
dotnet_diagnostic.CA2208.severity = warning
|
||||
|
||||
# CA2245: Do not assign a property to itself
|
||||
dotnet_diagnostic.CA2245.severity = warning
|
||||
|
||||
# CA2246: Assigning symbol and its member in the same statement
|
||||
dotnet_diagnostic.CA2246.severity = warning
|
||||
|
||||
# CA2249: Use string.Contains instead of string.IndexOf to improve readability.
|
||||
dotnet_diagnostic.CA2249.severity = warning
|
||||
|
||||
# IDE0005: Remove unnecessary usings
|
||||
dotnet_diagnostic.IDE0005.severity = warning
|
||||
|
||||
# IDE0011: Curly braces to surround blocks of code
|
||||
dotnet_diagnostic.IDE0011.severity = warning
|
||||
|
||||
# IDE0020: Use pattern matching to avoid is check followed by a cast (with variable)
|
||||
dotnet_diagnostic.IDE0020.severity = warning
|
||||
|
||||
# IDE0029: Use coalesce expression (non-nullable types)
|
||||
dotnet_diagnostic.IDE0029.severity = warning
|
||||
|
||||
# IDE0030: Use coalesce expression (nullable types)
|
||||
dotnet_diagnostic.IDE0030.severity = warning
|
||||
|
||||
# IDE0031: Use null propagation
|
||||
dotnet_diagnostic.IDE0031.severity = warning
|
||||
|
||||
# IDE0035: Remove unreachable code
|
||||
dotnet_diagnostic.IDE0035.severity = warning
|
||||
|
||||
# IDE0036: Order modifiers
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||
dotnet_diagnostic.IDE0036.severity = warning
|
||||
|
||||
# IDE0038: Use pattern matching to avoid is check followed by a cast (without variable)
|
||||
dotnet_diagnostic.IDE0038.severity = warning
|
||||
|
||||
# IDE0043: Format string contains invalid placeholder
|
||||
dotnet_diagnostic.IDE0043.severity = warning
|
||||
|
||||
# IDE0044: Make field readonly
|
||||
dotnet_diagnostic.IDE0044.severity = warning
|
||||
|
||||
# IDE0051: Remove unused private members
|
||||
dotnet_diagnostic.IDE0051.severity = warning
|
||||
|
||||
# IDE0055: All formatting rules
|
||||
dotnet_diagnostic.IDE0055.severity = suggestion
|
||||
|
||||
# IDE0059: Unnecessary assignment to a value
|
||||
dotnet_diagnostic.IDE0059.severity = warning
|
||||
|
||||
# IDE0060: Remove unused parameter
|
||||
dotnet_code_quality_unused_parameters = non_public
|
||||
dotnet_diagnostic.IDE0060.severity = warning
|
||||
|
||||
# IDE0062: Make local function static
|
||||
dotnet_diagnostic.IDE0062.severity = warning
|
||||
|
||||
# IDE0161: Convert to file-scoped namespace
|
||||
dotnet_diagnostic.IDE0161.severity = warning
|
||||
|
||||
# IDE0200: Lambda expression can be removed
|
||||
dotnet_diagnostic.IDE0200.severity = warning
|
||||
|
||||
# IDE2000: Disallow multiple blank lines
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = false
|
||||
dotnet_diagnostic.IDE2000.severity = warning
|
||||
|
||||
[{test,tests,testassets,examples,perf,scripts,stress}/**.cs]
|
||||
# CA1018: Mark attributes with AttributeUsageAttribute
|
||||
dotnet_diagnostic.CA1018.severity = suggestion
|
||||
# CA1507: Use nameof to express symbol names
|
||||
dotnet_diagnostic.CA1507.severity = suggestion
|
||||
# CA1510: Use ArgumentNullException throw helper
|
||||
dotnet_diagnostic.CA1510.severity = suggestion
|
||||
# CA1511: Use ArgumentException throw helper
|
||||
dotnet_diagnostic.CA1511.severity = suggestion
|
||||
# CA1512: Use ArgumentOutOfRangeException throw helper
|
||||
dotnet_diagnostic.CA1512.severity = suggestion
|
||||
# CA1513: Use ObjectDisposedException throw helper
|
||||
dotnet_diagnostic.CA1513.severity = suggestion
|
||||
# CA1802: Use literals where appropriate
|
||||
dotnet_diagnostic.CA1802.severity = suggestion
|
||||
# CA1805: Do not initialize unnecessarily
|
||||
dotnet_diagnostic.CA1805.severity = suggestion
|
||||
# CA1810: Do not initialize unnecessarily
|
||||
dotnet_diagnostic.CA1810.severity = suggestion
|
||||
# CA1822: Make member static
|
||||
dotnet_diagnostic.CA1822.severity = suggestion
|
||||
# CA1823: Avoid zero-length array allocations
|
||||
dotnet_diagnostic.CA1825.severity = suggestion
|
||||
# CA1826: Do not use Enumerable methods on indexable collections. Instead use the collection directly
|
||||
dotnet_diagnostic.CA1826.severity = suggestion
|
||||
# CA1827: Do not use Count() or LongCount() when Any() can be used
|
||||
dotnet_diagnostic.CA1827.severity = suggestion
|
||||
# CA1829: Use Length/Count property instead of Count() when available
|
||||
dotnet_diagnostic.CA1829.severity = suggestion
|
||||
# CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
||||
dotnet_diagnostic.CA1834.severity = suggestion
|
||||
# CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
|
||||
dotnet_diagnostic.CA1835.severity = suggestion
|
||||
# CA1837: Use 'Environment.ProcessId'
|
||||
dotnet_diagnostic.CA1837.severity = suggestion
|
||||
# CA1838: Avoid 'StringBuilder' parameters for P/Invokes
|
||||
dotnet_diagnostic.CA1838.severity = suggestion
|
||||
# CA1841: Prefer Dictionary.Contains methods
|
||||
dotnet_diagnostic.CA1841.severity = suggestion
|
||||
# CA1844: Provide memory-based overrides of async methods when subclassing 'Stream'
|
||||
dotnet_diagnostic.CA1844.severity = suggestion
|
||||
# CA1845: Use span-based 'string.Concat'
|
||||
dotnet_diagnostic.CA1845.severity = suggestion
|
||||
# CA1846: Prefer AsSpan over Substring
|
||||
dotnet_diagnostic.CA1846.severity = suggestion
|
||||
# CA1847: Use string.Contains(char) instead of string.Contains(string) with single characters
|
||||
dotnet_diagnostic.CA1847.severity = suggestion
|
||||
# CA1852: Seal internal types
|
||||
dotnet_diagnostic.CA1852.severity = suggestion
|
||||
# CA1854: Prefer the IDictionary.TryGetValue(TKey, out TValue) method
|
||||
dotnet_diagnostic.CA1854.severity = suggestion
|
||||
# CA1855: Prefer 'Clear' over 'Fill'
|
||||
dotnet_diagnostic.CA1855.severity = suggestion
|
||||
# CA1856: Incorrect usage of ConstantExpected attribute
|
||||
dotnet_diagnostic.CA1856.severity = suggestion
|
||||
# CA1857: A constant is expected for the parameter
|
||||
dotnet_diagnostic.CA1857.severity = suggestion
|
||||
# CA1858: Use 'StartsWith' instead of 'IndexOf'
|
||||
dotnet_diagnostic.CA1858.severity = suggestion
|
||||
# CA2007: Consider calling ConfigureAwait on the awaited task
|
||||
dotnet_diagnostic.CA2007.severity = suggestion
|
||||
# CA2008: Do not create tasks without passing a TaskScheduler
|
||||
dotnet_diagnostic.CA2008.severity = suggestion
|
||||
# CA2012: Use ValueTask correctly
|
||||
dotnet_diagnostic.CA2012.severity = suggestion
|
||||
# CA2249: Use string.Contains instead of string.IndexOf to improve readability.
|
||||
dotnet_diagnostic.CA2249.severity = suggestion
|
||||
# IDE0005: Remove unnecessary usings
|
||||
dotnet_diagnostic.IDE0005.severity = suggestion
|
||||
# IDE0020: Use pattern matching to avoid is check followed by a cast (with variable)
|
||||
dotnet_diagnostic.IDE0020.severity = suggestion
|
||||
# IDE0029: Use coalesce expression (non-nullable types)
|
||||
dotnet_diagnostic.IDE0029.severity = suggestion
|
||||
# IDE0030: Use coalesce expression (nullable types)
|
||||
dotnet_diagnostic.IDE0030.severity = suggestion
|
||||
# IDE0031: Use null propagation
|
||||
dotnet_diagnostic.IDE0031.severity = suggestion
|
||||
# IDE0038: Use pattern matching to avoid is check followed by a cast (without variable)
|
||||
dotnet_diagnostic.IDE0038.severity = suggestion
|
||||
# IDE0044: Make field readonly
|
||||
dotnet_diagnostic.IDE0044.severity = suggestion
|
||||
# IDE0051: Remove unused private members
|
||||
dotnet_diagnostic.IDE0051.severity = suggestion
|
||||
# IDE0059: Unnecessary assignment to a value
|
||||
dotnet_diagnostic.IDE0059.severity = suggestion
|
||||
# IDE0060: Remove unused parameters
|
||||
dotnet_diagnostic.IDE0060.severity = suggestion
|
||||
# IDE0062: Make local function static
|
||||
dotnet_diagnostic.IDE0062.severity = suggestion
|
||||
# IDE0200: Lambda expression can be removed
|
||||
dotnet_diagnostic.IDE0200.severity = suggestion
|
||||
|
||||
# CA2016: Forward the 'CancellationToken' parameter to methods that take one
|
||||
dotnet_diagnostic.CA2016.severity = suggestion
|
|
@ -0,0 +1,5 @@
|
|||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Issue with Grpc.Core
|
||||
url: https://github.com/grpc/grpc/issues/new/choose
|
||||
about: Please open issues relating to Grpc.Core in grpc/grpc.
|
|
@ -0,0 +1,46 @@
|
|||
name: Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ '**' ]
|
||||
schedule:
|
||||
- cron: 0 0 * * * # daily at 00:00
|
||||
|
||||
env:
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Basic Tests
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dotnet
|
||||
run: ./build/get-dotnet.sh
|
||||
|
||||
- name: Build and run tests
|
||||
run: ./build_and_test.sh
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: artifacts
|
||||
path: artifacts
|
||||
if-no-files-found: error
|
||||
|
||||
grpc_web:
|
||||
name: gRPC-Web Tests
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run interop tests
|
||||
run: ./grpcweb_interoptests.sh
|
|
@ -34,7 +34,6 @@ launchSettings.json
|
|||
BenchmarkDotNet.Artifacts/
|
||||
BDN.Generated/
|
||||
binaries/
|
||||
global.json
|
||||
.vscode/
|
||||
*.binlog
|
||||
build/feed
|
||||
|
|
14
.travis.yml
14
.travis.yml
|
@ -1,14 +0,0 @@
|
|||
language: csharp
|
||||
sudo: required
|
||||
dist: xenial
|
||||
env:
|
||||
global:
|
||||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
mono: none
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
install:
|
||||
- ./build/get-dotnet.sh
|
||||
script:
|
||||
- ./build_and_test.sh
|
|
@ -1,6 +1,4 @@
|
|||
<Project>
|
||||
<Import Project="build\sources.props" />
|
||||
<Import Project="build\dependencies.props" />
|
||||
<Import Project="build\version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
|
@ -12,12 +10,23 @@
|
|||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)keys\Grpc.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
|
||||
|
||||
<!-- Don't make missing XML docs a fatal build error, but still surface so we have visibility into undocumented APIs. -->
|
||||
<WarningsNotAsErrors>$(WarningsNotAsErrors);CS1591</WarningsNotAsErrors>
|
||||
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<!-- Disable warnings about AOT and trimming features on older targets, e.g. netstandard2.0.
|
||||
For now, continue to apply these features to these targets because some packages don't have a target that supports them -->
|
||||
<NoWarn>$(NoWarn);NETSDK1195;NETSDK1210</NoWarn>
|
||||
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<LangVersion>12.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
<!-- Some packages generate warnings when used on TFMs that are out of support (or almost out of support) -->
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -17,14 +17,38 @@
|
|||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
|
||||
<CodeAnalysisRuleset>$(MSBuildThisFileDirectory)Grpc.DotNet.ruleset</CodeAnalysisRuleset>
|
||||
|
||||
<IsTrimmable>true</IsTrimmable>
|
||||
<EnableAOTAnalyzer>true</EnableAOTAnalyzer>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- IsGrpcPublishedPackage is set in csproj so related config must be in targets file -->
|
||||
<ItemGroup Condition="'$(IsGrpcPublishedPackage)' == 'true'">
|
||||
<None Include="$(PackageIconFullPath)" Pack="true" PackagePath="\"/>
|
||||
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="$(MicrosoftCodeAnalysisFxCopAnalyzersPackageVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="$(MicrosoftSourceLinkGitHubPackageVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="$(MSBuildProjectName.EndsWith('Tests'))">
|
||||
<Using Include="NUnit.Framework.Legacy.ClassicAssert" Alias="Assert" />
|
||||
<Using Include="NUnit.Framework.Legacy" />
|
||||
<Using Include="NUnit.Framework" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
Make a netstandard2.1 copy of the .net ILLinkPack to work around a trimming issue.
|
||||
See https://github.com/dotnet/linker/issues/3175
|
||||
TODO: Remove once .NET 8 + trimming + netstandard2.1 is fixed.
|
||||
-->
|
||||
<Target Name="_FixKnownILLinkPack"
|
||||
BeforeTargets="ProcessFrameworkReferences">
|
||||
<ItemGroup>
|
||||
<KnownILLinkPack Include="@(KnownILLinkPack)"
|
||||
Condition="'%(TargetFramework)' == 'net8.0'"
|
||||
TargetFramework="netstandard2.1"
|
||||
ILLinkPackVersion="%(KnownILLinkPack.ILLinkPackVersion)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<MicrosoftAspNetCoreAppPackageVersion>10.0.0-preview.6.25358.103</MicrosoftAspNetCoreAppPackageVersion>
|
||||
<MicrosoftAspNetCoreApp9PackageVersion>9.0.4</MicrosoftAspNetCoreApp9PackageVersion>
|
||||
<MicrosoftAspNetCoreApp8PackageVersion>8.0.15</MicrosoftAspNetCoreApp8PackageVersion>
|
||||
<GrpcDotNetPackageVersion>2.70.0</GrpcDotNetPackageVersion>
|
||||
<OpenTelemetryPackageVersion>1.6.0</OpenTelemetryPackageVersion>
|
||||
<OpenTelemetryIntergationPackageVersion>1.8.1</OpenTelemetryIntergationPackageVersion>
|
||||
<OpenTelemetryGrpcPackageVersion>1.8.0-beta.1</OpenTelemetryGrpcPackageVersion>
|
||||
<MicrosoftExtensionsPackageVersion>10.0.0-preview.6.25358.103</MicrosoftExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsLtsPackageVersion>8.0.0</MicrosoftExtensionsLtsPackageVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- ASP.NET Core -->
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Certificate" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Grpc.JsonTranscoding" Version="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Grpc.Swagger" Version="0.8.0" />
|
||||
|
||||
<!-- Extensions -->
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsPackageVersion)" />
|
||||
|
||||
<!-- gRPC -->
|
||||
<PackageVersion Include="Grpc.Tools" Version="2.71.0" />
|
||||
<PackageVersion Include="Grpc.Core" Version="2.46.6" />
|
||||
<PackageVersion Include="Grpc.Core.Api" Version="$(GrpcDotNetPackageVersion)"/>
|
||||
<PackageVersion Include="Grpc.Net.Client" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.Net.Client.Web" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.Net.ClientFactory" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.AspNetCore" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.AspNetCore.Server" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.AspNetCore.Web" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.Reflection" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.AspNetCore.Server.Reflection" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.HealthCheck" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.AspNetCore.HealthChecks" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.Auth" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageVersion Include="Grpc.StatusProto" Version="$(GrpcDotNetPackageVersion)" />
|
||||
|
||||
<!-- OpenTelemetry -->
|
||||
<PackageVersion Include="OpenTelemetry" Version="$(OpenTelemetryPackageVersion)" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.Zipkin" Version="$(OpenTelemetryPackageVersion)" />
|
||||
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="$(OpenTelemetryPackageVersion)" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="$(OpenTelemetryIntergationPackageVersion)" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="$(OpenTelemetryGrpcPackageVersion)" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="$(OpenTelemetryIntergationPackageVersion)" />
|
||||
|
||||
<!-- Other -->
|
||||
<PackageVersion Include="BenchmarkDotNet" Version="0.15.2" />
|
||||
<PackageVersion Include="CommandLineParser" Version="2.5.0" />
|
||||
<PackageVersion Include="Google.Api.CommonProtos" Version="2.16.0" />
|
||||
<PackageVersion Include="Google.Apis.Auth" Version="1.70.0" />
|
||||
<PackageVersion Include="Google.Protobuf" Version="3.31.1" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Build.Locator" Version="1.5.5" />
|
||||
<PackageVersion Include="Microsoft.Build" Version="17.3.2" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.0-preview.25358.103" />
|
||||
<PackageVersion Include="Microsoft.Crank.EventSources" Version="0.2.0-alpha.25128.2" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Win32.Registry" Version="4.6.0" />
|
||||
<PackageVersion Include="Moq" Version="4.20.70" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="Nunit" Version="4.3.2" />
|
||||
<PackageVersion Include="NUnit3TestAdapter" Version="5.0.0" />
|
||||
<PackageVersion Include="protobuf-net.Grpc.AspNetCore" Version="1.0.140" />
|
||||
<PackageVersion Include="protobuf-net.Grpc" Version="1.0.140" />
|
||||
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
<PackageVersion Include="System.CommandLine.Rendering" Version="0.4.0-alpha.22272.1" />
|
||||
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Memory" Version="4.5.3" />
|
||||
<PackageVersion Include="System.Net.Http.WinHttpHandler" Version="8.0.3" />
|
||||
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0" />
|
||||
<PackageVersion Include="System.Text.Json" Version="8.0.6" />
|
||||
<PackageVersion Include="System.Threading.Channels" Version="4.6.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
250
Grpc.DotNet.sln
250
Grpc.DotNet.sln
|
@ -1,250 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28527.54
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8C62055F-8CD7-4859-9001-634D544DF2AE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{CECC4AE8-9C4E-4727-939B-517CC2E58D65}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore.Server", "src\Grpc.AspNetCore.Server\Grpc.AspNetCore.Server.csproj", "{89ED416F-92F1-4425-9379-D4E76A285860}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore.Server.Tests", "test\Grpc.AspNetCore.Server.Tests\Grpc.AspNetCore.Server.Tests.csproj", "{278B1311-41BF-4345-947E-7B70E277FC3C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore.FunctionalTests", "test\FunctionalTests\Grpc.AspNetCore.FunctionalTests.csproj", "{B190F61D-854C-4EE1-9532-B81AB3215F90}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "perf", "perf", "{4163E1B3-4D75-46B4-9107-9A158FD708FC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{59C7B1F0-EE4D-4098-8596-0ADDBC305234}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Proto", "Proto", "{BF1393D4-6099-4EF9-85BB-7EE6CBEB920C}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
testassets\Proto\any.proto = testassets\Proto\any.proto
|
||||
testassets\Proto\authorize.proto = testassets\Proto\authorize.proto
|
||||
testassets\Proto\chat.proto = testassets\Proto\chat.proto
|
||||
testassets\Proto\compression.proto = testassets\Proto\compression.proto
|
||||
testassets\Proto\count.proto = testassets\Proto\count.proto
|
||||
testassets\Proto\greet.proto = testassets\Proto\greet.proto
|
||||
testassets\Proto\lifetime.proto = testassets\Proto\lifetime.proto
|
||||
testassets\Proto\nested.proto = testassets\Proto\nested.proto
|
||||
examples\Proto\race.proto = examples\Proto\race.proto
|
||||
testassets\Proto\singleton.proto = testassets\Proto\singleton.proto
|
||||
testassets\Proto\streaming.proto = testassets\Proto\streaming.proto
|
||||
testassets\Proto\unimplemented.proto = testassets\Proto\unimplemented.proto
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTestsWebsite", "testassets\FunctionalTestsWebsite\FunctionalTestsWebsite.csproj", "{7B95289B-4992-4C0D-B26F-8EC58F81FC96}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarkapps", "benchmarkapps", "{1B8B6117-CE39-4580-BAFA-D8026102767A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkClient", "perf\benchmarkapps\BenchmarkClient\BenchmarkClient.csproj", "{B10D4986-25D2-4414-B500-627D89505914}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{310E5783-455A-4D09-A7AE-39DC2AB09504}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
perf\benchmarkapps\Shared\benchmark_service.proto = perf\benchmarkapps\Shared\benchmark_service.proto
|
||||
perf\benchmarkapps\Shared\BenchmarkConfigurationHelpers.cs = perf\benchmarkapps\Shared\BenchmarkConfigurationHelpers.cs
|
||||
perf\benchmarkapps\Shared\BenchmarkServiceImpl.cs = perf\benchmarkapps\Shared\BenchmarkServiceImpl.cs
|
||||
perf\benchmarkapps\Shared\messages.proto = perf\benchmarkapps\Shared\messages.proto
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore.Microbenchmarks", "perf\Grpc.AspNetCore.Microbenchmarks\Grpc.AspNetCore.Microbenchmarks.csproj", "{98500D54-FC3F-4A42-B74D-51930C19B175}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropTestsWebsite", "testassets\InteropTestsWebsite\InteropTestsWebsite.csproj", "{A551D7B1-D75A-43F0-A8E3-BAEA5EDF616A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkWorkerWebsite", "testassets\BenchmarkWorkerWebsite\BenchmarkWorkerWebsite.csproj", "{C3D6C3BD-4E56-4B0F-88FD-4F2D68F0CD25}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Certs", "Certs", "{39320CA8-D8F0-45B6-B704-A04C16870226}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
perf\benchmarkapps\Shared\Certs\testCert.pfx = perf\benchmarkapps\Shared\Certs\testCert.pfx
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore.Server.Reflection", "src\Grpc.AspNetCore.Server.Reflection\Grpc.AspNetCore.Server.Reflection.csproj", "{55813F20-1269-4B19-B03E-7E4A90148F92}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropTestsClient", "testassets\InteropTestsClient\InteropTestsClient.csproj", "{291E5BA5-608D-406D-A2DB-389412D907F3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Certs", "Certs", "{743F8EC2-004E-4640-B04F-5BAFDA8BF112}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "InteropTests", "InteropTests", "{50CF39FF-2644-4B5F-BE1A-B57487B9723B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
testassets\Certs\InteropTests\ca.pem = testassets\Certs\InteropTests\ca.pem
|
||||
testassets\Certs\InteropTests\README.md = testassets\Certs\InteropTests\README.md
|
||||
testassets\Certs\InteropTests\server1.key = testassets\Certs\InteropTests\server1.key
|
||||
testassets\Certs\InteropTests\server1.pem = testassets\Certs\InteropTests\server1.pem
|
||||
testassets\Certs\InteropTests\server1.pfx = testassets\Certs\InteropTests\server1.pfx
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc", "grpc", "{6DC078D2-8FB1-4685-B9BE-61F1C0ED8053}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testing", "testing", "{88AC787E-603C-48C3-AEBA-D90F3E2142CA}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
testassets\Proto\grpc\testing\empty.proto = testassets\Proto\grpc\testing\empty.proto
|
||||
testassets\Proto\grpc\testing\messages.proto = testassets\Proto\grpc\testing\messages.proto
|
||||
testassets\Proto\grpc\testing\test.proto = testassets\Proto\grpc\testing\test.proto
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteropTestsNativeServer", "testassets\InteropTestsNativeServer\InteropTestsNativeServer.csproj", "{D15CAEF6-0A5D-416E-B6F7-DE75C4B1D89B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-grpc", "src\dotnet-grpc\dotnet-grpc.csproj", "{EBD5D978-1519-45ED-AC20-EC43C7FA552C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-grpc.Tests", "test\dotnet-grpc.Tests\dotnet-grpc.Tests.csproj", "{265CD0AA-A1BD-40B8-A1E6-B3CB5F7591B8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore.Server.ClientFactory", "src\Grpc.AspNetCore.Server.ClientFactory\Grpc.AspNetCore.Server.ClientFactory.csproj", "{BF9F5674-2BC3-446E-BBEA-3055A4A2B889}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore.Server.ClientFactory.Tests", "test\Grpc.AspNetCore.Server.ClientFactory.Tests\Grpc.AspNetCore.Server.ClientFactory.Tests.csproj", "{4306E048-9D81-44A8-8069-2C294289FC00}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Net.Client", "src\Grpc.Net.Client\Grpc.Net.Client.csproj", "{095F2B46-16DC-4A2E-A075-A0373D902294}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Net.Client.Tests", "test\Grpc.Net.Client.Tests\Grpc.Net.Client.Tests.csproj", "{7C299E2C-A5FE-439D-A346-2A676302BD04}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Net.ClientFactory", "src\Grpc.Net.ClientFactory\Grpc.Net.ClientFactory.csproj", "{F68DBD76-196A-4F55-BBEB-97278655017F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Net.ClientFactory.Tests", "test\Grpc.Net.ClientFactory.Tests\Grpc.Net.ClientFactory.Tests.csproj", "{0C98BD64-8A57-46A1-B47B-EAF260DEE25A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.AspNetCore", "src\Grpc.AspNetCore\Grpc.AspNetCore.csproj", "{F6CA82C9-85C6-4A5F-B892-4DF8A20B1C05}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Net.Common", "src\Grpc.Net.Common\Grpc.Net.Common.csproj", "{69C50655-71EE-4E69-BC2C-ABCA568F6E76}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrpcAspNetCoreServer", "perf\benchmarkapps\GrpcAspNetCoreServer\GrpcAspNetCoreServer.csproj", "{1D9AB69D-244C-4871-867E-DCEC52B552A4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrpcCoreServer", "perf\benchmarkapps\GrpcCoreServer\GrpcCoreServer.csproj", "{781111FC-8F3C-433E-BC96-D88ADAEE3064}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{89ED416F-92F1-4425-9379-D4E76A285860}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{89ED416F-92F1-4425-9379-D4E76A285860}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{89ED416F-92F1-4425-9379-D4E76A285860}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{89ED416F-92F1-4425-9379-D4E76A285860}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{278B1311-41BF-4345-947E-7B70E277FC3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{278B1311-41BF-4345-947E-7B70E277FC3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{278B1311-41BF-4345-947E-7B70E277FC3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{278B1311-41BF-4345-947E-7B70E277FC3C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B190F61D-854C-4EE1-9532-B81AB3215F90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B190F61D-854C-4EE1-9532-B81AB3215F90}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B190F61D-854C-4EE1-9532-B81AB3215F90}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B190F61D-854C-4EE1-9532-B81AB3215F90}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7B95289B-4992-4C0D-B26F-8EC58F81FC96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7B95289B-4992-4C0D-B26F-8EC58F81FC96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7B95289B-4992-4C0D-B26F-8EC58F81FC96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7B95289B-4992-4C0D-B26F-8EC58F81FC96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B10D4986-25D2-4414-B500-627D89505914}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B10D4986-25D2-4414-B500-627D89505914}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B10D4986-25D2-4414-B500-627D89505914}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B10D4986-25D2-4414-B500-627D89505914}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{98500D54-FC3F-4A42-B74D-51930C19B175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{98500D54-FC3F-4A42-B74D-51930C19B175}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{98500D54-FC3F-4A42-B74D-51930C19B175}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98500D54-FC3F-4A42-B74D-51930C19B175}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A551D7B1-D75A-43F0-A8E3-BAEA5EDF616A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A551D7B1-D75A-43F0-A8E3-BAEA5EDF616A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A551D7B1-D75A-43F0-A8E3-BAEA5EDF616A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A551D7B1-D75A-43F0-A8E3-BAEA5EDF616A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C3D6C3BD-4E56-4B0F-88FD-4F2D68F0CD25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C3D6C3BD-4E56-4B0F-88FD-4F2D68F0CD25}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C3D6C3BD-4E56-4B0F-88FD-4F2D68F0CD25}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C3D6C3BD-4E56-4B0F-88FD-4F2D68F0CD25}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{55813F20-1269-4B19-B03E-7E4A90148F92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{55813F20-1269-4B19-B03E-7E4A90148F92}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{55813F20-1269-4B19-B03E-7E4A90148F92}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{55813F20-1269-4B19-B03E-7E4A90148F92}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{291E5BA5-608D-406D-A2DB-389412D907F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{291E5BA5-608D-406D-A2DB-389412D907F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{291E5BA5-608D-406D-A2DB-389412D907F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{291E5BA5-608D-406D-A2DB-389412D907F3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D15CAEF6-0A5D-416E-B6F7-DE75C4B1D89B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D15CAEF6-0A5D-416E-B6F7-DE75C4B1D89B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D15CAEF6-0A5D-416E-B6F7-DE75C4B1D89B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D15CAEF6-0A5D-416E-B6F7-DE75C4B1D89B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EBD5D978-1519-45ED-AC20-EC43C7FA552C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EBD5D978-1519-45ED-AC20-EC43C7FA552C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EBD5D978-1519-45ED-AC20-EC43C7FA552C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EBD5D978-1519-45ED-AC20-EC43C7FA552C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{265CD0AA-A1BD-40B8-A1E6-B3CB5F7591B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{265CD0AA-A1BD-40B8-A1E6-B3CB5F7591B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{265CD0AA-A1BD-40B8-A1E6-B3CB5F7591B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{265CD0AA-A1BD-40B8-A1E6-B3CB5F7591B8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BF9F5674-2BC3-446E-BBEA-3055A4A2B889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BF9F5674-2BC3-446E-BBEA-3055A4A2B889}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BF9F5674-2BC3-446E-BBEA-3055A4A2B889}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BF9F5674-2BC3-446E-BBEA-3055A4A2B889}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4306E048-9D81-44A8-8069-2C294289FC00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4306E048-9D81-44A8-8069-2C294289FC00}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4306E048-9D81-44A8-8069-2C294289FC00}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4306E048-9D81-44A8-8069-2C294289FC00}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{095F2B46-16DC-4A2E-A075-A0373D902294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{095F2B46-16DC-4A2E-A075-A0373D902294}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{095F2B46-16DC-4A2E-A075-A0373D902294}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{095F2B46-16DC-4A2E-A075-A0373D902294}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7C299E2C-A5FE-439D-A346-2A676302BD04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7C299E2C-A5FE-439D-A346-2A676302BD04}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7C299E2C-A5FE-439D-A346-2A676302BD04}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7C299E2C-A5FE-439D-A346-2A676302BD04}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F68DBD76-196A-4F55-BBEB-97278655017F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F68DBD76-196A-4F55-BBEB-97278655017F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F68DBD76-196A-4F55-BBEB-97278655017F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F68DBD76-196A-4F55-BBEB-97278655017F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0C98BD64-8A57-46A1-B47B-EAF260DEE25A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0C98BD64-8A57-46A1-B47B-EAF260DEE25A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0C98BD64-8A57-46A1-B47B-EAF260DEE25A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0C98BD64-8A57-46A1-B47B-EAF260DEE25A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F6CA82C9-85C6-4A5F-B892-4DF8A20B1C05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F6CA82C9-85C6-4A5F-B892-4DF8A20B1C05}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F6CA82C9-85C6-4A5F-B892-4DF8A20B1C05}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F6CA82C9-85C6-4A5F-B892-4DF8A20B1C05}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{69C50655-71EE-4E69-BC2C-ABCA568F6E76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{69C50655-71EE-4E69-BC2C-ABCA568F6E76}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{69C50655-71EE-4E69-BC2C-ABCA568F6E76}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{69C50655-71EE-4E69-BC2C-ABCA568F6E76}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1D9AB69D-244C-4871-867E-DCEC52B552A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1D9AB69D-244C-4871-867E-DCEC52B552A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1D9AB69D-244C-4871-867E-DCEC52B552A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1D9AB69D-244C-4871-867E-DCEC52B552A4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{781111FC-8F3C-433E-BC96-D88ADAEE3064}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{781111FC-8F3C-433E-BC96-D88ADAEE3064}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{781111FC-8F3C-433E-BC96-D88ADAEE3064}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{781111FC-8F3C-433E-BC96-D88ADAEE3064}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{89ED416F-92F1-4425-9379-D4E76A285860} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{278B1311-41BF-4345-947E-7B70E277FC3C} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
|
||||
{B190F61D-854C-4EE1-9532-B81AB3215F90} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
|
||||
{59C7B1F0-EE4D-4098-8596-0ADDBC305234} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
|
||||
{BF1393D4-6099-4EF9-85BB-7EE6CBEB920C} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
|
||||
{7B95289B-4992-4C0D-B26F-8EC58F81FC96} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
|
||||
{1B8B6117-CE39-4580-BAFA-D8026102767A} = {4163E1B3-4D75-46B4-9107-9A158FD708FC}
|
||||
{B10D4986-25D2-4414-B500-627D89505914} = {1B8B6117-CE39-4580-BAFA-D8026102767A}
|
||||
{310E5783-455A-4D09-A7AE-39DC2AB09504} = {1B8B6117-CE39-4580-BAFA-D8026102767A}
|
||||
{98500D54-FC3F-4A42-B74D-51930C19B175} = {4163E1B3-4D75-46B4-9107-9A158FD708FC}
|
||||
{A551D7B1-D75A-43F0-A8E3-BAEA5EDF616A} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
|
||||
{C3D6C3BD-4E56-4B0F-88FD-4F2D68F0CD25} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
|
||||
{39320CA8-D8F0-45B6-B704-A04C16870226} = {310E5783-455A-4D09-A7AE-39DC2AB09504}
|
||||
{55813F20-1269-4B19-B03E-7E4A90148F92} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{291E5BA5-608D-406D-A2DB-389412D907F3} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
|
||||
{743F8EC2-004E-4640-B04F-5BAFDA8BF112} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
|
||||
{50CF39FF-2644-4B5F-BE1A-B57487B9723B} = {743F8EC2-004E-4640-B04F-5BAFDA8BF112}
|
||||
{6DC078D2-8FB1-4685-B9BE-61F1C0ED8053} = {BF1393D4-6099-4EF9-85BB-7EE6CBEB920C}
|
||||
{88AC787E-603C-48C3-AEBA-D90F3E2142CA} = {6DC078D2-8FB1-4685-B9BE-61F1C0ED8053}
|
||||
{D15CAEF6-0A5D-416E-B6F7-DE75C4B1D89B} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
|
||||
{EBD5D978-1519-45ED-AC20-EC43C7FA552C} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{265CD0AA-A1BD-40B8-A1E6-B3CB5F7591B8} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
|
||||
{BF9F5674-2BC3-446E-BBEA-3055A4A2B889} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{4306E048-9D81-44A8-8069-2C294289FC00} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
|
||||
{095F2B46-16DC-4A2E-A075-A0373D902294} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{7C299E2C-A5FE-439D-A346-2A676302BD04} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
|
||||
{F68DBD76-196A-4F55-BBEB-97278655017F} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{0C98BD64-8A57-46A1-B47B-EAF260DEE25A} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
|
||||
{F6CA82C9-85C6-4A5F-B892-4DF8A20B1C05} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{69C50655-71EE-4E69-BC2C-ABCA568F6E76} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
|
||||
{1D9AB69D-244C-4871-867E-DCEC52B552A4} = {1B8B6117-CE39-4580-BAFA-D8026102767A}
|
||||
{781111FC-8F3C-433E-BC96-D88ADAEE3064} = {1B8B6117-CE39-4580-BAFA-D8026102767A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {CD5C2B19-49B4-480A-990C-36D98A719B07}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,90 @@
|
|||
<Solution>
|
||||
<Folder Name="/perf/">
|
||||
<Project Path="perf/Grpc.AspNetCore.Microbenchmarks/Grpc.AspNetCore.Microbenchmarks.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/perf/benchmarkapps/">
|
||||
<Project Path="perf/benchmarkapps/GrpcAspNetCoreServer/GrpcAspNetCoreServer.csproj" />
|
||||
<Project Path="perf/benchmarkapps/GrpcClient/GrpcClient.csproj" />
|
||||
<Project Path="perf/benchmarkapps/GrpcCoreServer/GrpcCoreServer.csproj" />
|
||||
<Project Path="perf/benchmarkapps/QpsWorker/QpsWorker.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/perf/benchmarkapps/Shared/">
|
||||
<File Path="perf/benchmarkapps/Shared/BenchmarkConfigurationHelpers.cs" />
|
||||
<File Path="perf/benchmarkapps/Shared/BenchmarkServiceImpl.cs" />
|
||||
<File Path="perf/benchmarkapps/Shared/benchmark_service.proto" />
|
||||
<File Path="perf/benchmarkapps/Shared/messages.proto" />
|
||||
</Folder>
|
||||
<Folder Name="/perf/benchmarkapps/Shared/Certs/">
|
||||
<File Path="perf/benchmarkapps/Shared/Certs/testCert.pfx" />
|
||||
</Folder>
|
||||
<Folder Name="/src/">
|
||||
<Project Path="src/dotnet-grpc/dotnet-grpc.csproj" />
|
||||
<Project Path="src/Grpc.AspNetCore.HealthChecks/Grpc.AspNetCore.HealthChecks.csproj" />
|
||||
<Project Path="src/Grpc.AspNetCore.Server.ClientFactory/Grpc.AspNetCore.Server.ClientFactory.csproj" />
|
||||
<Project Path="src/Grpc.AspNetCore.Server.Reflection/Grpc.AspNetCore.Server.Reflection.csproj" />
|
||||
<Project Path="src/Grpc.AspNetCore.Server/Grpc.AspNetCore.Server.csproj" />
|
||||
<Project Path="src/Grpc.AspNetCore.Web/Grpc.AspNetCore.Web.csproj" />
|
||||
<Project Path="src/Grpc.AspNetCore/Grpc.AspNetCore.csproj" />
|
||||
<Project Path="src/Grpc.Auth/Grpc.Auth.csproj" />
|
||||
<Project Path="src/Grpc.Core.Api/Grpc.Core.Api.csproj" />
|
||||
<Project Path="src/Grpc.HealthCheck/Grpc.HealthCheck.csproj" />
|
||||
<Project Path="src/Grpc.Net.Client.Web/Grpc.Net.Client.Web.csproj" />
|
||||
<Project Path="src/Grpc.Net.Client/Grpc.Net.Client.csproj" />
|
||||
<Project Path="src/Grpc.Net.ClientFactory/Grpc.Net.ClientFactory.csproj" />
|
||||
<Project Path="src/Grpc.Net.Common/Grpc.Net.Common.csproj" />
|
||||
<Project Path="src/Grpc.Reflection/Grpc.Reflection.csproj" />
|
||||
<Project Path="src/Grpc.StatusProto/Grpc.StatusProto.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/tests/">
|
||||
<Project Path="test/dotnet-grpc.Tests/dotnet-grpc.Tests.csproj" />
|
||||
<Project Path="test/FunctionalTests/Grpc.AspNetCore.FunctionalTests.csproj" />
|
||||
<Project Path="test/Grpc.AspNetCore.Server.ClientFactory.Tests/Grpc.AspNetCore.Server.ClientFactory.Tests.csproj" />
|
||||
<Project Path="test/Grpc.AspNetCore.Server.Tests/Grpc.AspNetCore.Server.Tests.csproj" />
|
||||
<Project Path="test/Grpc.Core.Api.Tests/Grpc.Core.Api.Tests.csproj" />
|
||||
<Project Path="test/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj" />
|
||||
<Project Path="test/Grpc.Net.Client.Tests/Grpc.Net.Client.Tests.csproj" />
|
||||
<Project Path="test/Grpc.Net.Client.Web.Tests/Grpc.Net.Client.Web.Tests.csproj" />
|
||||
<Project Path="test/Grpc.Net.ClientFactory.Tests/Grpc.Net.ClientFactory.Tests.csproj" />
|
||||
<Project Path="test/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj" />
|
||||
<Project Path="test/Grpc.StatusProto.Tests/Grpc.StatusProto.Tests.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/tests/testassets/">
|
||||
<Project Path="testassets/BenchmarkWorkerWebsite/BenchmarkWorkerWebsite.csproj" />
|
||||
<Project Path="testassets/FunctionalTestsWebsite/FunctionalTestsWebsite.csproj" />
|
||||
<Project Path="testassets/InteropTestsClient/InteropTestsClient.csproj" />
|
||||
<Project Path="testassets/InteropTestsGrpcWebClient/InteropTestsGrpcWebClient.csproj" />
|
||||
<Project Path="testassets/InteropTestsGrpcWebWebsite/InteropTestsGrpcWebWebsite.csproj" />
|
||||
<Project Path="testassets/InteropTestsNativeServer/InteropTestsNativeServer.csproj" />
|
||||
<Project Path="testassets/InteropTestsWebsite/InteropTestsWebsite.csproj" />
|
||||
<Project Path="testassets/LinkerTestsClient/LinkerTestsClient.csproj" />
|
||||
<Project Path="testassets/LinkerTestsWebsite/LinkerTestsWebsite.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/tests/testassets/Certs/" />
|
||||
<Folder Name="/tests/testassets/Certs/InteropTests/">
|
||||
<File Path="testassets/Certs/InteropTests/ca.pem" />
|
||||
<File Path="testassets/Certs/InteropTests/README.md" />
|
||||
<File Path="testassets/Certs/InteropTests/server1.key" />
|
||||
<File Path="testassets/Certs/InteropTests/server1.pem" />
|
||||
<File Path="testassets/Certs/InteropTests/server1.pfx" />
|
||||
</Folder>
|
||||
<Folder Name="/tests/testassets/Proto/">
|
||||
<File Path="examples/Proto/race.proto" />
|
||||
<File Path="testassets/Proto/any.proto" />
|
||||
<File Path="testassets/Proto/authorize.proto" />
|
||||
<File Path="testassets/Proto/chat.proto" />
|
||||
<File Path="testassets/Proto/compression.proto" />
|
||||
<File Path="testassets/Proto/count.proto" />
|
||||
<File Path="testassets/Proto/greet.proto" />
|
||||
<File Path="testassets/Proto/lifetime.proto" />
|
||||
<File Path="testassets/Proto/nested.proto" />
|
||||
<File Path="testassets/Proto/singleton.proto" />
|
||||
<File Path="testassets/Proto/streaming.proto" />
|
||||
<File Path="testassets/Proto/unimplemented.proto" />
|
||||
</Folder>
|
||||
<Folder Name="/tests/testassets/Proto/grpc/" />
|
||||
<Folder Name="/tests/testassets/Proto/grpc/testing/">
|
||||
<File Path="testassets/Proto/grpc/testing/empty.proto" />
|
||||
<File Path="testassets/Proto/grpc/testing/messages.proto" />
|
||||
<File Path="testassets/Proto/grpc/testing/test.proto" />
|
||||
</Folder>
|
||||
</Solution>
|
|
@ -8,10 +8,17 @@ See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIB
|
|||
for general contribution guidelines.
|
||||
|
||||
## Maintainers (in alphabetical order)
|
||||
- [adityamandaleeka](https://github.com/adityamandaleeka), Microsoft Corporation
|
||||
- [amcasey](https://github.com/amcasey), Microsoft Corporation
|
||||
- [apolcyn](https://github.com/apolcyn), Google LLC
|
||||
- [benjaminpetit](https://github.com/benjaminpetit), Microsoft Corporation
|
||||
- [BrennanConroy](https://github.com/BrennanConroy), Microsoft Corporation
|
||||
- [davidfowl](https://github.com/davidfowl), Microsoft Corporation
|
||||
- [JamesNK](https://github.com/JamesNK), Microsoft Corporation
|
||||
- [jtattermusch](https://github.com/jtattermusch), Google LLC
|
||||
- [JunTaoLuo](https://github.com/JunTaoLuo), Microsoft Corporation
|
||||
- [mgravell](https://github.com/mgravell), Microsoft Corporation
|
||||
- [ReubenBond](https://github.com/ReubenBond), Microsoft Corporation
|
||||
- [stanley-cheung](https://github.com/stanley-cheung), Google LLC
|
||||
|
||||
## Emeritus Maintainers (in alphabetical order)
|
||||
- [jtattermusch](https://github.com/jtattermusch)
|
||||
- [JunTaoLuo](https://github.com/JunTaoLuo)
|
||||
|
|
23
README.md
23
README.md
|
@ -1,22 +1,23 @@
|
|||
# gRPC for .NET
|
||||
|
||||
## Available now on .NET Core 3.0!
|
||||
|
||||
gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. gRPC enables client and server applications to communicate transparently, and simplifies the building of connected systems.
|
||||
|
||||
gRPC functionality for .NET Core 3.0 includes:
|
||||
gRPC functionality for .NET Core 3.0 or later includes:
|
||||
|
||||
* [Grpc.AspNetCore](https://www.nuget.org/packages/Grpc.AspNetCore) – An ASP.NET Core framework for hosting gRPC services. gRPC on ASP.NET Core integrates with standard ASP.NET Core features like logging, dependency injection (DI), authentication and authorization.
|
||||
* [Grpc.Net.Client](https://www.nuget.org/packages/Grpc.Net.Client) – A gRPC client for .NET Core that builds upon the familiar `HttpClient`. The client uses new HTTP/2 functionality in .NET Core.
|
||||
* [Grpc.Net.ClientFactory](https://www.nuget.org/packages/Grpc.Net.ClientFactory) – gRPC client integration with `HttpClientFactory`. The client factory allows gRPC clients to be centrally configured and injected into your app with DI.
|
||||
|
||||
Please note that gRPC for .NET does not replace [gRPC for C#](https://github.com/grpc/grpc/tree/master/src/csharp) (gRPC C# API over native C-core binaries). These implementations coexist and share many of the same APIs to avoid lock-in. There are currently no plans for one implementation to replace the other one. gRPC for C# is the recommended solution for frameworks that gRPC for .NET does not support, such as .NET Framework.
|
||||
|
||||
For more information, see [An introduction to gRPC on .NET](https://docs.microsoft.com/aspnet/core/grpc/).
|
||||
|
||||
## gRPC for .NET is now the recommended implementation!
|
||||
|
||||
Starting from May 2021, gRPC for .NET is the recommended implemention of gRPC for C#. The original [gRPC for C#](https://github.com/grpc/grpc/tree/master/src/csharp) implementation (distributed as the `Grpc.Core` nuget package) is now in maintenance mode and will be deprecated in the future.
|
||||
See [blogpost](https://grpc.io/blog/grpc-csharp-future/) for more details.
|
||||
|
||||
## To start using gRPC for .NET
|
||||
|
||||
The best place to start using gRPC for .NET is the gRPC template that comes with .NET Core 3.0. Use the template to [create a gRPC service website and client](https://docs.microsoft.com/aspnet/core/tutorials/grpc/grpc-start).
|
||||
The best place to start using gRPC for .NET is the gRPC template that comes with .NET Core 3.0 or later. Use the template to [create a gRPC service website and client](https://docs.microsoft.com/aspnet/core/tutorials/grpc/grpc-start).
|
||||
|
||||
For additional examples of using gRPC in .NET refer to https://github.com/grpc/grpc-dotnet/tree/master/examples.
|
||||
|
||||
|
@ -61,14 +62,20 @@ startvs.cmd
|
|||
|
||||
To build from the command line:
|
||||
```
|
||||
dotnet build Grpc.DotNet.sln
|
||||
dotnet build Grpc.DotNet.slnx
|
||||
```
|
||||
|
||||
To run tests from the command line:
|
||||
```
|
||||
dotnet test Grpc.DotNet.sln
|
||||
dotnet test Grpc.DotNet.slnx
|
||||
```
|
||||
|
||||
### Alternative implementation using Code-First (external library)
|
||||
|
||||
An alternative way to use gRPC in .NET is to define the Protobuf contracts directly in C# using [protobuf-net](https://github.com/protobuf-net/protobuf-net.Grpc).
|
||||
|
||||
For more information, see the documentation on [learn.microsoft.com](https://learn.microsoft.com/aspnet/core/grpc/code-first) or the [protobuf-net.Grpc website](https://protobuf-net.github.io/protobuf-net.Grpc/).
|
||||
|
||||
## To contribute
|
||||
|
||||
Contributions are welcome!
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<BenchmarkDotNetPackageVersion>0.11.3</BenchmarkDotNetPackageVersion>
|
||||
<CommandLineParserPackageVersion>2.3.0</CommandLineParserPackageVersion>
|
||||
<GoogleProtobufPackageVersion>3.10.0</GoogleProtobufPackageVersion>
|
||||
<GrpcDotNetPackageVersion>2.25.0</GrpcDotNetPackageVersion> <!-- Only use for example projects -->
|
||||
<GrpcPackageVersion>2.25.0</GrpcPackageVersion>
|
||||
<MicrosoftAspNetCorePackageVersion>3.0.0</MicrosoftAspNetCorePackageVersion>
|
||||
<MicrosoftBuildLocatorPackageVersion>1.2.2</MicrosoftBuildLocatorPackageVersion>
|
||||
<MicrosoftBuildPackageVersion>16.0.461</MicrosoftBuildPackageVersion>
|
||||
<MicrosoftCodeAnalysisFxCopAnalyzersPackageVersion>2.9.4</MicrosoftCodeAnalysisFxCopAnalyzersPackageVersion>
|
||||
<MicrosoftExtensionsPackageVersion>2.1.1</MicrosoftExtensionsPackageVersion>
|
||||
<MicrosoftExtensions30PackageVersion>3.0.0</MicrosoftExtensions30PackageVersion>
|
||||
<MicrosoftNETTestSdkPackageVersion>16.2.0</MicrosoftNETTestSdkPackageVersion>
|
||||
<MicrosoftSourceLinkGitHubPackageVersion>1.0.0-beta2-19367-01</MicrosoftSourceLinkGitHubPackageVersion>
|
||||
<MicrosoftWin32RegistryLinePackageVersion>4.6.0</MicrosoftWin32RegistryLinePackageVersion>
|
||||
<MoqPackageVersion>4.10.0</MoqPackageVersion>
|
||||
<NewtonsoftJsonPackageVersion>12.0.2</NewtonsoftJsonPackageVersion>
|
||||
<NunitPackageVersion>3.12.0</NunitPackageVersion>
|
||||
<Nunit3TestAdapterPackageVersion>3.13.0</Nunit3TestAdapterPackageVersion>
|
||||
<OpenTelemetryPackageVersion>0.2.0-alpha.100</OpenTelemetryPackageVersion>
|
||||
<SystemCommandLinePackageVersion>0.3.0-alpha.19405.1</SystemCommandLinePackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.5.1</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemSecurityPrincipalWindowsPackageVersion>4.6.0</SystemSecurityPrincipalWindowsPackageVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -27,4 +27,11 @@ echo "Downloading install script: $install_script_url => $install_script_path"
|
|||
curl -sSL -o $install_script_path $install_script_url
|
||||
chmod +x $install_script_path
|
||||
|
||||
# Install .NET 8 SDK to run 8.0 test targets
|
||||
$install_script_path -v 8.0.412 -i $dotnet_install_path
|
||||
|
||||
# Install .NET 9 SDK to run 9.0 test targets
|
||||
$install_script_path -v 9.0.303 -i $dotnet_install_path
|
||||
|
||||
# Install .NET version specified by global.json
|
||||
$install_script_path -v $sdk_version -i $dotnet_install_path
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup Label="RestoreSources">
|
||||
<RestoreSources>
|
||||
$(RestoreSources);
|
||||
https://api.nuget.org/v3/index.json;
|
||||
https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore/index.json;
|
||||
https://dotnetfeed.blob.core.windows.net/aspnet-extensions/index.json;
|
||||
https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
|
||||
https://dotnet.myget.org/F/roslyn/api/v3/index.json;
|
||||
</RestoreSources>
|
||||
<RestoreSources Condition="Exists('$(MSBuildThisFileDirectory)feed')">
|
||||
$(RestoreSources);
|
||||
$(MSBuildThisFileDirectory)feed;
|
||||
</RestoreSources>
|
||||
<!-- The following is used to ingest nightly gRPC packages -->
|
||||
<RestoreSources>
|
||||
$(RestoreSources);
|
||||
https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev;
|
||||
</RestoreSources>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2022 The gRPC Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Update Grpc.Core.Api's VersionInfo.cs with versions from version.props
|
||||
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# retrieve version strings from version.props
|
||||
PACKAGE_VERSION=$(grep -o '<GrpcDotnetVersion>.*</GrpcDotnetVersion>' version.props | sed 's/<GrpcDotnetVersion>//' | sed 's/<\/GrpcDotnetVersion>//')
|
||||
ASSEMBLY_VERSION=$(grep -o '<GrpcDotnetAssemblyVersion>.*</GrpcDotnetAssemblyVersion>' version.props | sed 's/<GrpcDotnetAssemblyVersion>//' | sed 's/<\/GrpcDotnetAssemblyVersion>//')
|
||||
ASSEMBLY_FILE_VERSION=$(grep -o '<GrpcDotnetAssemblyFileVersion>.*</GrpcDotnetAssemblyFileVersion>' version.props | sed 's/<GrpcDotnetAssemblyFileVersion>//' | sed 's/<\/GrpcDotnetAssemblyFileVersion>//')
|
||||
|
||||
# update the contents of src/Grpc.Core.Api/VersionInfo.cs with the version strings
|
||||
sed -i "s/CurrentVersion = \".*\"/CurrentVersion = \"${PACKAGE_VERSION}\"/g" ../src/Grpc.Core.Api/VersionInfo.cs
|
||||
sed -i "s/CurrentAssemblyVersion = \".*\"/CurrentAssemblyVersion = \"${ASSEMBLY_VERSION}\"/g" ../src/Grpc.Core.Api/VersionInfo.cs
|
||||
sed -i "s/CurrentAssemblyFileVersion = \".*\"/CurrentAssemblyFileVersion = \"${ASSEMBLY_FILE_VERSION}\"/g" ../src/Grpc.Core.Api/VersionInfo.cs
|
||||
|
||||
echo "Updated version strings in src/Grpc.Core.Api/VersionInfo.cs"
|
|
@ -2,13 +2,13 @@
|
|||
<PropertyGroup>
|
||||
|
||||
<!-- package version of grpc-dotnet -->
|
||||
<GrpcDotnetVersion>2.26.0-dev</GrpcDotnetVersion>
|
||||
|
||||
<GrpcDotnetVersion>2.66.0-dev</GrpcDotnetVersion>
|
||||
|
||||
<!-- assembly version of grpc-dotnet -->
|
||||
<GrpcDotnetAssemblyVersion>2.0.0.0</GrpcDotnetAssemblyVersion>
|
||||
|
||||
<!-- file version of all grpc-dotnet -->
|
||||
<GrpcDotnetAssemblyFileVersion>2.26.0.0</GrpcDotnetAssemblyFileVersion>
|
||||
<GrpcDotnetAssemblyFileVersion>2.66.0.0</GrpcDotnetAssemblyFileVersion>
|
||||
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
|
@ -22,32 +22,21 @@ echo "Building solution"
|
|||
dotnet build -c Release
|
||||
|
||||
echo "Building examples"
|
||||
|
||||
example_solutions=( $( ls examples/**/*.sln ) )
|
||||
|
||||
example_solutions=( $( ls examples/**/*.slnx ) )
|
||||
for example_solution in "${example_solutions[@]}"
|
||||
do
|
||||
dotnet build $example_solution -c Release
|
||||
done
|
||||
|
||||
echo "Testing solution"
|
||||
|
||||
has_failures=false
|
||||
test_projects=( $( ls test/**/*Tests.csproj ) )
|
||||
|
||||
for test_project in "${test_projects[@]}"
|
||||
do
|
||||
# "dotnet test" is hanging when it writes to console for an unknown reason
|
||||
# Tracking issue at https://github.com/microsoft/vstest/issues/2080
|
||||
# Write test output to a text file and then write the text file to console as a workaround
|
||||
{
|
||||
dotnet test $test_project -c Release -v n --no-build &> ${test_project##*/}.log.txt &&
|
||||
echo "Success" &&
|
||||
cat ${test_project##*/}.log.txt
|
||||
} || {
|
||||
echo "Failure" &&
|
||||
cat ${test_project##*/}.log.txt &&
|
||||
exit 1
|
||||
}
|
||||
base_name=$(basename ${test_project%.*})
|
||||
dotnet test $test_project -c Release --no-build --logger "trx;LogFilePrefix=$base_name" --results-directory artifacts/test-results -- NUnit.ConsoleOut=0 || has_failures=true
|
||||
done
|
||||
|
||||
echo "Finished"
|
||||
if [ "$has_failures" = true ]; then
|
||||
exit 1
|
||||
fi
|
|
@ -11,23 +11,60 @@ This document summarizes the differences between the two available implementatio
|
|||
|
||||
## Criteria for choosing between grpc-dotnet and gRPC C#
|
||||
|
||||
One might choose one or the other implementation mostly for one of these reasons
|
||||
Starting from May 2021, gRPC for .NET is the recommended implemention of gRPC for C#.
|
||||
The original [gRPC C#](https://github.com/grpc/grpc/tree/master/src/csharp) implementation (distributed as the `Grpc.Core` nuget package) is now in maintenance mode and will be deprecated in the future.
|
||||
See [blogpost](https://grpc.io/blog/grpc-csharp-future/) for more details.
|
||||
|
||||
- avoid use of native code
|
||||
- ability to use .NET Core 3 and ASP.NET Core 3 (it's a brand new stack so not everyone will be able to use immediately)
|
||||
- want seamless integration with ASP.NET Core 3, dependency injection etc.
|
||||
- features available (see breakdown)
|
||||
- maturity level
|
||||
- performance (TODO: add data)
|
||||
Here are some key points in which the two implementation differ:
|
||||
|
||||
- grpc-dotnet avoids the use of native code (while Grpc.Core use the native C-core library internally)
|
||||
- grpc-dotnet requires a newer version of .NET (see the "Framework supported" section)
|
||||
- grpc-dotnet server integrates seamlessly ASP.NET Core (and allows e.g. dependency injection)
|
||||
- performance (while data we have data that seems to indicate that grpc-dotnet peforms at least as well as Grpc.Core, we strongly encourage to run your own benchmarks if performance matters for your application)
|
||||
- features available (see breakdown below)
|
||||
|
||||
## Frameworks supported
|
||||
|
||||
Grpc.Core supports a wide range of .NET versions, including some very old ones. A more detailed overview is [here]( https://github.com/grpc/grpc/tree/master/src/csharp#supported-platforms)
|
||||
|
||||
grpc-dotnet uses features only available in modern .NET releases. It doesn't support some older versions of .NET. A detailed summary of .NET versions supported by grpc-dotnet is [here](https://docs.microsoft.com/aspnet/core/grpc/supported-platforms). There is limited support for [grpc-dotnet client support on
|
||||
legacy .NET Framework](https://docs.microsoft.com/aspnet/core/grpc/netstandard).
|
||||
|
||||
## Comparison of supported features
|
||||
|
||||
Beyond the basic RPC functionality, there are a lot of gRPC features that may or may not be supported. The summary
|
||||
of supported features in both implementation is available in this section.
|
||||
|
||||
### Proxyless service mesh (XDS) support
|
||||
|
||||
While support for some of the Proxyless service mesh functionality comes "for free" by virtue of using the implementation from C-core native library, we don't officially support the proxyless service mesh functionality in C#.
|
||||
|
||||
In grpc-dotnet, we currently don't provide proxyless service mesh support, but it's something that we plan to add in the future. One of the first features we want to integrate is XDS load balancing.
|
||||
|
||||
### Load Balancing
|
||||
|
||||
grpc-dotnet and Grpc.Core provides basic client load balancing policies PICK_FIRST, ROUND_ROBIN.
|
||||
|
||||
Grpc.Core also has implemented two client-lookaside LB policies, but we don't recommend using them:
|
||||
|
||||
- grpclb - limited use externally as there's no official implementation of the LB policy. We don't recommend using it as it's been deprecated by the XDS load balancing.
|
||||
- XDS - Load balancing using the Envoy Universal Data Plane APIs (xDS). It does work in Grpc.Core (because it's implemented in C-core native library), but as noted above, we don't provide official support for the proxyless service mesh functionality in Grpc.Core.
|
||||
|
||||
Proxy load balancing is supported by both implementations because load balancing is done by a separate process (e.g. Envoy, ngingx etc.) that proxies the traffic.
|
||||
|
||||
grpc-dotnet allows user-provided custom load-balancing policies (= a plugin that provides the load-balancing logic).
|
||||
|
||||
Also see:
|
||||
|
||||
- https://learn.microsoft.com/aspnet/core/grpc/loadbalancing
|
||||
- https://github.com/grpc/grpc/blob/master/doc/load-balancing.md
|
||||
- https://github.com/grpc/grpc/blob/master/doc/naming.md
|
||||
- https://github.com/grpc/proposal/blob/master/A5-grpclb-in-dns.md
|
||||
- https://github.com/grpc/proposal/blob/master/A24-lb-policy-config.md
|
||||
|
||||
### Service config
|
||||
|
||||
Service config is currently only supported by Grpc.Core. Right now the feature is not that useful
|
||||
Service config is supported by grpc-dotnet and Grpc.Core. Right now, the feature is not that useful
|
||||
because support for service config encoded in DNS records hasn't been enabled yet by default.
|
||||
|
||||
Also see:
|
||||
|
@ -45,52 +82,36 @@ Grpc.Core: currently not supported.
|
|||
|
||||
Both implementations support client and server interceptors from Grpc.Core.Interceptors namespace. Interceptors operate at post-deserialization and pre-serialization level (no access to binary payloads).
|
||||
|
||||
In addition to gRPC-aware interceptors, grpc-dotnet also allows interception at a HTTP/2 level:
|
||||
In addition to gRPC-aware interceptors, grpc-dotnet also allows interception at an HTTP/2 level:
|
||||
|
||||
- Incoming gRPC HTTP/2 requests can be processed using [ASP.NET Core middleware](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/).
|
||||
- Outgoing gRPC HTTP/2 requests can be processed using [HttpClient HttpMessageHandlers](https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpmessagehandler).
|
||||
|
||||
### Load Balancing
|
||||
|
||||
Grpc.Core provides basic client load balancing policies PICK_FIRST, ROUND_ROBIN and client-lookaside LB policies:
|
||||
|
||||
- grpclb - limited use externally as there's no official implementation of the LB policy
|
||||
- XDS - Load balancing using the Envoy Universal Data Plane APIs (xDS). Currently this is work in progress but once ready, it will be the LB of choice for lookaside LB.
|
||||
|
||||
grpc-dotnet currently doesn't provide any loadbalancing policies. It is likely that to support the XDS loadbalancing policy, features will need to be added to .NET HttpClient.
|
||||
|
||||
Proxy loadbalancing is supported by both implementations because loadbalancing is done by a separate process (e.g. Envoy, ngingx etc.) that proxies the traffic.
|
||||
|
||||
None of the implementations currently allow user-provided custom loadbalancing policies (= a plugin that provides the loadbalancing logic).
|
||||
|
||||
- https://github.com/grpc/grpc/blob/master/doc/load-balancing.md
|
||||
- https://github.com/grpc/grpc/blob/master/doc/naming.md
|
||||
- https://github.com/grpc/proposal/blob/master/A5-grpclb-in-dns.md
|
||||
- https://github.com/grpc/proposal/blob/master/A24-lb-policy-config.md
|
||||
|
||||
### Transport support
|
||||
|
||||
Both implementations fully support gRPC over HTTP/2 in both TLS and plaintext.
|
||||
|
||||
Grpc.Core gets support for other transports supported by C-Core for free. Some (minor) integration work might be required to actually use these transports with gRPC C#.
|
||||
|
||||
grpc-dotnet only supports the default transport.
|
||||
grpc-dotnet supports other transports in .NET 5 or later. For example, grpc-dotnet [supports interprocess communication (IPC)](https://learn.microsoft.com/aspnet/core/grpc/interprocess) using named pipes and Unix domain sockets.
|
||||
|
||||
Notes:
|
||||
|
||||
- Grpc.Core allows connections over UDS socket (both server and client) on Unix systems. It doesn't support named pipes on windows.
|
||||
- Grpc.Core supports additional "transports" like ALTS and cfstream thanks to being build on top of C-core.
|
||||
- Grpc.Core could provide an inprocess transport support but currently this functionality is not exposed in C# API.
|
||||
- grpc-dotnet support for TLS is platform dependent. TLS is fully supported on Windows and Linux, but doesn't work on MacOS.
|
||||
- grpc-dotnet support UDS socket on the server-side (On Unix systems, but also on [Windows](https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/))
|
||||
- grpc-dotnet support for TLS is platform dependent. TLS is fully supported on Windows and Linux. There is limited support for servers hosted on MacOS prior to .NET 8.
|
||||
|
||||
### Retries / Request Hedging
|
||||
|
||||
Grpc.Core: implementation in C-core in progress, but no ETA yet
|
||||
|
||||
grpc-dotnet: not implemented
|
||||
grpc-dotnet: Retries and hedging are fully supported.
|
||||
|
||||
https://github.com/grpc/proposal/blob/master/A6-client-retries.md,
|
||||
Also see:
|
||||
|
||||
- https://learn.microsoft.com/aspnet/core/grpc/retries
|
||||
- https://github.com/grpc/proposal/blob/master/A6-client-retries.md
|
||||
|
||||
### Channelz
|
||||
|
||||
|
@ -112,7 +133,7 @@ https://github.com/grpc/grpc/blob/master/doc/binary-logging.md
|
|||
|
||||
Grpc.Core: supported (algorithms: `gzip`, `deflate`)
|
||||
|
||||
grpc-dotnet: supported (algorithms: `gzip`), also provides public API to provide custom compression algorithm.
|
||||
grpc-dotnet: supported (algorithms: `gzip`, `deflate`), also provides public API to provide custom compression algorithm.
|
||||
|
||||
Performance implications of using compression in both implementations haven't been measured. Compression functionality is offered mostly to comply with the spec.
|
||||
|
||||
|
@ -123,7 +144,7 @@ https://github.com/grpc/grpc/blob/master/doc/compression_cookbook.md
|
|||
|
||||
Grpc.Core: supported (exposed publicly on Channel), provided by C-Core
|
||||
|
||||
grpc-dotnet: not supported (to provide support, changes to .NET HttpClient are needed, so adding support is non-trivial).
|
||||
grpc-dotnet: Supported on .NET 5 or later
|
||||
|
||||
https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md
|
||||
|
||||
|
@ -147,7 +168,7 @@ https://github.com/grpc/grpc/blob/master/doc/keepalive.md
|
|||
|
||||
Grpc.Core: supported, provided by C-core
|
||||
|
||||
grpc-dotnet: not supported (implementing the wait_for_ready flag requires supporting channel connectivity first).
|
||||
grpc-dotnet: Supported on .NET 5 or later
|
||||
|
||||
https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md
|
||||
|
||||
|
@ -155,7 +176,7 @@ https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md
|
|||
|
||||
Grpc.Core: conforms with the spec thanks to the C-core dependency. It is currently not possible to provide custom C# resolvers via resolver API (the APIs are in C core and aren't exposed in the C# layer).
|
||||
|
||||
grpc-dotnet: only resolves basic DNS names. No API to provide a custom resolver.
|
||||
grpc-dotnet: Resolving is fully supported on .NET 5 or later. grpc-dotnet also provides an [API to write custom resolvers](https://learn.microsoft.com/aspnet/core/grpc/loadbalancingwrite-custom-resolvers-and-load-balancers).
|
||||
|
||||
https://github.com/grpc/grpc/blob/master/doc/naming.md
|
||||
|
||||
|
@ -165,7 +186,7 @@ grpc-dotnet allows port-sharing: serving both gRPC and non-gRPC traffic by the s
|
|||
|
||||
## Add-on Features
|
||||
|
||||
Features that don't necessarily require changes to implementation's internals. They usually come as a separate opt-in nuget package.
|
||||
Features that don't necessarily require changes to the implementation's internals. They usually come as a separate opt-in nuget package.
|
||||
|
||||
### Addon: Server Reflection
|
||||
Grpc.Core: supported via Grpc.Reflection nuget package
|
||||
|
@ -197,4 +218,22 @@ grpc-dotnet supports integration with `HttpClientFactory` via the Grpc.Net.Clien
|
|||
- Reuse of channel instances.
|
||||
- Automatic propagation of cancellation and deadline when used in a `Grpc.AspNetCore` hosted gRPC service.
|
||||
|
||||
https://docs.microsoft.com/en-us/aspnet/core/grpc/clientfactory
|
||||
### Addon: gRPC JSON transcoding
|
||||
|
||||
grpc-dotnet supports providing a RESTful JSON API using [gRPC JSON transcoding](https://learn.microsoft.com/aspnet/core/grpc/json-transcoding).
|
||||
|
||||
gRPC JSON transcoding is an extension for ASP.NET Core that creates RESTful JSON APIs for gRPC services. Once configured, transcoding allows apps to call gRPC services with familiar HTTP concepts:
|
||||
|
||||
- HTTP verbs
|
||||
- URL parameter binding
|
||||
- JSON requests/responses
|
||||
|
||||
gRPC can still be used to call services.
|
||||
|
||||
### Addon: gRPC-Web
|
||||
|
||||
grpc-dotnet supports the [gRPC-Web protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md).
|
||||
|
||||
gRPC-Web allows browser JavaScript and Blazor apps to call gRPC services. It's not possible to call a gRPC service over HTTP/2 from a browser-based app. gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside gRPC over HTTP/2.
|
||||
|
||||
https://learn.microsoft.com/aspnet/core/grpc/grpcweb
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
# gRPC-dotnet future planning (for ASP.NET Core 5.0)
|
||||
|
||||
## Schedule and versioning
|
||||
|
||||
The work described here targets the ASP.NET Core 5.0 release which is currently scheduled for November 2020: https://github.com/dotnet/core/blob/master/roadmap.md. The version of the gRPC-dotnet release will follow the rules laid out in https://github.com/grpc/grpc-dotnet/blob/master/doc/versioning.md.
|
||||
|
||||
## Runtime
|
||||
|
||||
- Linker-friendly gRPC
|
||||
- As part of positioning .NET as a viable technology for cloud native, we should ensure we are linker-friendly and audit any possible future usage of reflection/ref-emit
|
||||
- Optimize for working-set memory/published output size
|
||||
- See https://github.com/rynowak/link-a-thon/blob/master/Findings.md for comparison
|
||||
|
||||
- Additional Server
|
||||
- HttpSysServer
|
||||
- IIS In-proc
|
||||
|
||||
- Introduce additional transports on the server
|
||||
- Unix-domain sockets
|
||||
- Named pipes (on Windows)
|
||||
- [Stretch] QUIC
|
||||
|
||||
- Introduce additional transports on the client
|
||||
- Unix-domain sockets
|
||||
- Named pipes (on Windows)
|
||||
- [Stretch] QUIC
|
||||
|
||||
- Serializer/de-serializer performance improvements
|
||||
- https://github.com/protocolbuffers/protobuf/pull/5888
|
||||
|
||||
- HTTP/2 performance on the server
|
||||
- HPACK Static dictionary
|
||||
- HPACK Dynamic dictionary
|
||||
- Pooling of HTTP/2 Streams
|
||||
- [Stretch] Window update tuning
|
||||
|
||||
- Ensure code-first gRPC is successful
|
||||
- Marc Gravell is using protobuf.net to build a code-first gRPC experience on grpc-dotnet. Ensure our abstractions allow him to be successful.
|
||||
|
||||
- Ensure WCF to gRPC ebook is successful
|
||||
- Provide SME guidance where applicable
|
||||
|
||||
- Testing existing client libraries on both implementations
|
||||
- There are APIs and SDKs to share between the implementations
|
||||
- https://github.com/grpc/grpc-dotnet/blob/master/doc/implementation_comparison.md
|
||||
- Here is the list of client libraries that grpc-dotnet should work with
|
||||
- https://github.com/googleapis/google-cloud-dotnet
|
||||
- there's an add-on library https://github.com/GoogleCloudPlatform/grpc-gcp-csharp that is used to provide some of the functionality (like channel affinity) for some of the APIs.
|
||||
|
||||
It would also be useful to help with figuring out a way to make the client libraries not depend on Grpc.Core directly (which is currently the case).
|
||||
|
||||
- Load balancing
|
||||
- Integration with XDS load balancing APIs
|
||||
- May need Connectivity APIs work in HttpClient
|
||||
- We should start with supporting round_robin loadbalancing as a first step. The features needed for that are very likely to be needed for XDS loadbalancing as well.
|
||||
|
||||
|
||||
- Connection Features
|
||||
- Keep alive, without keepalive support it can be difficult to have long-lived streaming call that only rarely sends messages (e.g. "client subscribes for receiving updates from server " scenario)
|
||||
- Connection idle: https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
|
||||
- Wait for ready
|
||||
- These features are often needed for production ready services
|
||||
|
||||
- Support status.proto
|
||||
- Trailing rich metadata for error details
|
||||
- Works across different implementation
|
||||
- For details, see "Richer error model" here: https://grpc.io/docs/guides/error/ and also https://cloud.google.com/apis/design/errors#error_model
|
||||
example what we've done for e.g. python: https://github.com/grpc/proposal/blob/master/L44-python-rich-status.md
|
||||
the expectation is that we'll ship this as a separate nuget (e.g. "Grpc.StatusProto")
|
||||
|
||||
|
||||
- Channelz support
|
||||
- Observability of server status
|
||||
|
||||
- gRPC web
|
||||
|
||||
## Tooling
|
||||
|
||||
- [Stretch] Build a LSP for protobuf
|
||||
- [Stretch] VS Code extension to consume LSP
|
||||
- [More Info Needed] Possibly partner with VS Code team here
|
||||
- [Stretch] VS Extension to consume LSP
|
||||
|
||||
- Tooling for working with gRPC services without building a client project
|
||||
- Integration with HttpREPL or something like WCFTestClient?
|
||||
|
||||
- Generating and working with client certificates
|
||||
|
||||
- Publishing to AKS
|
||||
|
||||
## Ecosystem
|
||||
|
||||
- Envoy integration
|
||||
- [Stretch] Integration with Envoy XDS APIs for client-side load balancing
|
||||
- Kubernetes/AKS
|
||||
- [More Info Needed] Helm charts for CLI publish
|
||||
- Xamarin apps support
|
||||
|
||||
## Documentation/Samples
|
||||
|
||||
- OAuth E2E
|
||||
- More AuthN/AuthZ coverage
|
||||
- gRPC specific features
|
||||
- Deadlines
|
||||
- Cancellation
|
||||
- Distributed Tracing
|
||||
- OpenCenus/Open Telemetry
|
||||
- Interceptors
|
||||
|
||||
## Intentional cuts/omissions
|
||||
|
||||
- gRPC with JSON (as opposed to protobuf)
|
|
@ -10,8 +10,9 @@ release that the new release depends on.
|
|||
## Releasing a new version of grpc-dotnet (every 6 weeks)
|
||||
|
||||
- Before cutting the release branch
|
||||
- If needed, on the master branch update the `<GrpcPackageVersion>` dependency version in [dependencies.props](https://github.com/grpc/grpc-dotnet/blob/master/build/dependencies.props)
|
||||
to the latest pre-release of `Grpc.Core.Api` (that was just released as part of the grpc/grpc release process)
|
||||
- If needed, on the master branch update the `Grpc.Tools` and `Grpc.Core` dependency versions in [Directory.Packages.props](https://github.com/grpc/grpc-dotnet/blob/master/Directory.Packages.props)
|
||||
to the latest pre-release of `Grpc.Tools` or `Grpc.Core` (that was released as part of the grpc/grpc release process)
|
||||
|
||||
- Make sure that any patches/bugfixes from the last released branch have been applied to the master branch as well.
|
||||
|
||||
- Cut the release branch from master branch (the branch format is `v2.25.x`, `v2.26.x`, ...).
|
||||
|
@ -19,22 +20,27 @@ release that the new release depends on.
|
|||
|
||||
- On the release branch, replace the `-dev` suffix by `-pre1` under `<GrpcDotnetVersion>` version release number in [version.props](https://github.com/grpc/grpc-dotnet/blob/master/build/version.props)
|
||||
to prepare for building the pre-release nugets.
|
||||
Also check that the minor version number matches the branch name.
|
||||
- You'll also need to update `CurrentVersion` field in `Grpc.Core.Api`'s [VersionInfo.cs](https://github.com/grpc/grpc-dotnet/blob/6bbbf3627797ad8f787eced10b0e548cfd9ece15/src/Grpc.Core.Api/VersionInfo.cs#L44) to match the version number (otherwise tests will fail).
|
||||
- Also check that the minor version number matches the branch name.
|
||||
|
||||
- Build the signed nuget packages and push them to nuget.org (internal process). **These are the pre-release packages.**
|
||||
|
||||
- Create a new release and tag in https://github.com/grpc/grpc-dotnet/releases (by creating the tag from the current release branch).
|
||||
Mark the release as "pre-release" in the github UI. Fill in the release notes.
|
||||
|
||||
- Wait for the stable release of `Grpc.Core.Api` (as scheduled by the release schedule), keep checking the issue tracker for problems with the new grpc-dotnet pre-release packages.
|
||||
- Wait for the stable release of `Grpc.Tools` from the `grpc/grpc` repository (as scheduled by the release schedule), keep checking the issue tracker for problems with the new grpc-dotnet pre-release packages.
|
||||
If problems are discovered and they need to be fixed, the release manager might choose to release more pre-releases (`-pre2`, `-pre3`, ...) before deciding to release as stable.
|
||||
|
||||
- **Make sure at least 7 days have elapsed since the last pre-release before proceeding with the stable release**, to give users enough time to test the prerelease nugets and discover potential issues. This is to decrease the likelyhood of pushing a bad stable release.
|
||||
|
||||
- Once stable version of `Grpc.Core.Api` is pushed, remove `-pre1` suffix of the `<GrpcDotnetVersion>` version release number in [version.props](https://github.com/grpc/grpc-dotnet/blob/master/build/version.props) to prepare for the stable release.
|
||||
- Once stable version of `Grpc.Tools` is pushed, remove `-pre1` suffix of the `<GrpcDotnetVersion>` version release number in [version.props](https://github.com/grpc/grpc-dotnet/blob/master/build/version.props) to prepare for the stable release.
|
||||
|
||||
- Update `CurrentVersion` field in `Grpc.Core.Api`'s [VersionInfo.cs](https://github.com/grpc/grpc-dotnet/blob/6bbbf3627797ad8f787eced10b0e548cfd9ece15/src/Grpc.Core.Api/VersionInfo.cs#L44) to match the version number (otherwise tests will fail).
|
||||
|
||||
- Build the signed nuget packages and push them to nuget.org (internal process). **These are the stable grpc-dotnet packages.**
|
||||
|
||||
- Create a new release and tag in https://github.com/grpc/grpc-dotnet/releases (by creating the tag from the current release branch).
|
||||
This is the stable release. Fill in the release notes.
|
||||
This is the stable release. Fill in the release notes and list changes since the previous _stable_ version.
|
||||
|
||||
### After the release
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
grpcweb-server:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./testassets/InteropTestsWebsite/Dockerfile
|
||||
image: grpc-dotnet/grpcweb-server
|
||||
ports:
|
||||
- "8080:80"
|
||||
grpcweb-client:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./testassets/InteropTestsGrpcWebWebsite/Dockerfile
|
||||
image: grpc-dotnet/grpcweb-client
|
||||
ports:
|
||||
- "8081:80"
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29230.61
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D22B3129-3BFB-41FA-9FCE-E45EBEF8C2DD}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,4 @@
|
|||
<Solution>
|
||||
<Project Path="Client/Client.csproj" />
|
||||
<Project Path="Server/Server.csproj" />
|
||||
</Solution>
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -10,9 +10,9 @@
|
|||
<Protobuf Include="..\Proto\greet.proto" GrpcServices="None" Link="Protos\greet.proto"/>
|
||||
<Protobuf Include="..\Proto\count.proto" GrpcServices="None" Link="Protos\count.proto"/>
|
||||
|
||||
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
|
||||
<PackageReference Include="Grpc.Net.Client" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageReference Include="Grpc.Tools" Version="$(GrpcPackageVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Google.Protobuf" />
|
||||
<PackageReference Include="Grpc.Net.Client" />
|
||||
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -16,72 +16,54 @@
|
|||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Aggregate;
|
||||
using Count;
|
||||
using Greet;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
|
||||
namespace Client
|
||||
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
|
||||
var client = new Aggregator.AggregatorClient(channel);
|
||||
|
||||
await ServerStreamingCallExample(client);
|
||||
|
||||
await ClientStreamingCallExample(client);
|
||||
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
|
||||
static async Task ServerStreamingCallExample(Aggregator.AggregatorClient client)
|
||||
{
|
||||
public class Program
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(3.5));
|
||||
|
||||
using var call = client.SayHellos(new HelloRequest { Name = "AggregatorClient" }, cancellationToken: cts.Token);
|
||||
try
|
||||
{
|
||||
static Random RNG = new Random();
|
||||
|
||||
static async Task Main(string[] args)
|
||||
await foreach (var message in call.ResponseStream.ReadAllAsync())
|
||||
{
|
||||
var channel = GrpcChannel.ForAddress("https://localhost:5001");
|
||||
var client = new Aggregator.AggregatorClient(channel);
|
||||
|
||||
await ServerStreamingCallExample(client);
|
||||
|
||||
await ClientStreamingCallExample(client);
|
||||
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
private static async Task ServerStreamingCallExample(Aggregator.AggregatorClient client)
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(3.5));
|
||||
|
||||
using (var replies = client.SayHellos(new HelloRequest { Name = "AggregatorClient" }, cancellationToken: cts.Token))
|
||||
{
|
||||
try
|
||||
{
|
||||
await foreach (var message in replies.ResponseStream.ReadAllAsync())
|
||||
{
|
||||
Console.WriteLine("Greeting: " + message.Message);
|
||||
}
|
||||
}
|
||||
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
|
||||
{
|
||||
Console.WriteLine("Stream cancelled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ClientStreamingCallExample(Aggregator.AggregatorClient client)
|
||||
{
|
||||
using (var call = client.AccumulateCount())
|
||||
{
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var count = RNG.Next(5);
|
||||
Console.WriteLine($"Accumulating with {count}");
|
||||
await call.RequestStream.WriteAsync(new CounterRequest { Count = count });
|
||||
await Task.Delay(2000);
|
||||
}
|
||||
|
||||
await call.RequestStream.CompleteAsync();
|
||||
|
||||
var response = await call;
|
||||
Console.WriteLine($"Count: {response.Count}");
|
||||
}
|
||||
Console.WriteLine("Greeting: " + message.Message);
|
||||
}
|
||||
}
|
||||
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
|
||||
{
|
||||
Console.WriteLine("Stream cancelled.");
|
||||
}
|
||||
}
|
||||
|
||||
static async Task ClientStreamingCallExample(Aggregator.AggregatorClient client)
|
||||
{
|
||||
using var call = client.AccumulateCount();
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var count = Random.Shared.Next(5);
|
||||
Console.WriteLine($"Accumulating with {count}");
|
||||
await call.RequestStream.WriteAsync(new CounterRequest { Count = count });
|
||||
await Task.Delay(2000);
|
||||
}
|
||||
|
||||
await call.RequestStream.CompleteAsync();
|
||||
|
||||
var response = await call;
|
||||
Console.WriteLine($"Count: {response.Count}");
|
||||
}
|
||||
|
|
|
@ -16,23 +16,59 @@
|
|||
|
||||
#endregion
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Count;
|
||||
using Greet;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
using Server;
|
||||
|
||||
namespace Server
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddGrpc();
|
||||
builder.Services.AddSingleton<IncrementingCounter>();
|
||||
|
||||
if (bool.TryParse(builder.Configuration["EnableOpenTelemetry"], out var enableOpenTelemetry) && enableOpenTelemetry)
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
builder.Services.AddOpenTelemetry()
|
||||
.WithTracing(tracing =>
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
tracing.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("aggregator"));
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
// We want to view all traces in development
|
||||
tracing.SetSampler(new AlwaysOnSampler());
|
||||
}
|
||||
|
||||
tracing.AddAspNetCoreInstrumentation()
|
||||
.AddGrpcClientInstrumentation()
|
||||
.AddHttpClientInstrumentation();
|
||||
|
||||
tracing.AddZipkinExporter();
|
||||
});
|
||||
}
|
||||
|
||||
// These clients will call back to the server
|
||||
builder.Services
|
||||
.AddGrpcClient<Greeter.GreeterClient>((s, o) => { o.Address = GetCurrentAddress(s); })
|
||||
.EnableCallContextPropagation();
|
||||
builder.Services
|
||||
.AddGrpcClient<Counter.CounterClient>((s, o) => { o.Address = GetCurrentAddress(s); })
|
||||
.EnableCallContextPropagation();
|
||||
|
||||
var app = builder.Build();
|
||||
app.MapGrpcService<GreeterService>();
|
||||
app.MapGrpcService<CounterService>();
|
||||
app.MapGrpcService<AggregatorService>();
|
||||
app.Run();
|
||||
|
||||
static Uri GetCurrentAddress(IServiceProvider serviceProvider)
|
||||
{
|
||||
// Get the address of the current server from the request
|
||||
var context = serviceProvider.GetRequiredService<IHttpContextAccessor>()?.HttpContext;
|
||||
if (context == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not get HttpContext.");
|
||||
}
|
||||
|
||||
return new Uri($"{context.Request.Scheme}://{context.Request.Host.Value}");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -9,12 +9,13 @@
|
|||
<Protobuf Include="..\Proto\greet.proto" GrpcServices="Both" Link="Protos\greet.proto" />
|
||||
<Protobuf Include="..\Proto\count.proto" GrpcServices="Both" Link="Protos\count.proto" />
|
||||
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageReference Include="Grpc.AspNetCore" />
|
||||
|
||||
<PackageReference Include="OpenTelemetry.Hosting" Version="$(OpenTelemetryPackageVersion)" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="$(OpenTelemetryPackageVersion)" />
|
||||
<PackageReference Include="OpenTelemetry.Collector.Dependencies" Version="$(OpenTelemetryPackageVersion)" />
|
||||
<PackageReference Include="OpenTelemetry.Collector.AspNetCore" Version="$(OpenTelemetryPackageVersion)" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Count;
|
||||
using Greet;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenTelemetry.Trace.Configuration;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public partial class Startup
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
private const string EnableOpenTelemetryKey = "EnableOpenTelemetry";
|
||||
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddGrpc();
|
||||
services.AddSingleton<IncrementingCounter>();
|
||||
|
||||
if (_configuration.GetValue<bool>(EnableOpenTelemetryKey))
|
||||
{
|
||||
services.AddOpenTelemetry(telemetry =>
|
||||
{
|
||||
telemetry.UseZipkin(o => o.ServiceName = "aggregator");
|
||||
telemetry.AddDependencyCollector();
|
||||
telemetry.AddRequestCollector();
|
||||
});
|
||||
}
|
||||
|
||||
// These clients will call back to the server
|
||||
services
|
||||
.AddGrpcClient<Greeter.GreeterClient>((s, o) => { o.Address = GetCurrentAddress(s); })
|
||||
.EnableCallContextPropagation();
|
||||
services
|
||||
.AddGrpcClient<Counter.CounterClient>((s, o) => { o.Address = GetCurrentAddress(s); })
|
||||
.EnableCallContextPropagation();
|
||||
|
||||
static Uri GetCurrentAddress(IServiceProvider serviceProvider)
|
||||
{
|
||||
// Get the address of the current server from the request
|
||||
var context = serviceProvider.GetRequiredService<IHttpContextAccessor>()?.HttpContext;
|
||||
if (context == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not get HttpContext.");
|
||||
}
|
||||
|
||||
return new Uri($"{context.Request.Scheme}://{context.Request.Host.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapGrpcService<GreeterService>();
|
||||
endpoints.MapGrpcService<CounterService>();
|
||||
endpoints.MapGrpcService<AggregatorService>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<Solution>
|
||||
<Project Path="Client/Client.csproj" />
|
||||
<Project Path="Server/Server.csproj" />
|
||||
</Solution>
|
|
@ -0,0 +1,10 @@
|
|||
<Router AppAssembly="@typeof(Program).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p>Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" PrivateAssets="all" />
|
||||
|
||||
<PackageReference Include="Google.Protobuf" />
|
||||
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
|
||||
<PackageReference Include="Grpc.Net.Client" />
|
||||
<PackageReference Include="Grpc.Net.Client.Web" />
|
||||
|
||||
<Protobuf Include="..\Proto\weather.proto" GrpcServices="Client" Link="Protos\weather.proto" Access="Internal" />
|
||||
<Protobuf Include="..\Proto\count.proto" GrpcServices="Client" Link="Protos\count.proto" Access="Internal" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -17,20 +17,20 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Grpc.AspNetCore.Server.Model;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
namespace FunctionalTestsWebsite.Infrastructure
|
||||
namespace Weather
|
||||
{
|
||||
public class DynamicServiceModelProvider : IServiceMethodProvider<DynamicService>
|
||||
// Properties for the underlying data are generated from the .proto file
|
||||
// This partial class just adds some extra convenience properties
|
||||
internal partial class WeatherForecast
|
||||
{
|
||||
public Action<ServiceMethodProviderContext<DynamicService>>? CreateMethod { get; set; }
|
||||
|
||||
public void OnServiceMethodDiscovery(ServiceMethodProviderContext<DynamicService> context)
|
||||
public DateTime DateTime
|
||||
{
|
||||
Debug.Assert(CreateMethod != null);
|
||||
|
||||
CreateMethod(context);
|
||||
get => Date.ToDateTime();
|
||||
set { Date = Timestamp.FromDateTime(value.ToUniversalTime()); }
|
||||
}
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
@page "/counter"
|
||||
@inject GrpcChannel Channel
|
||||
@using Grpc.Core
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p>Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount" disabled="@(cts != null)">Start</button>
|
||||
<button class="btn btn-primary" @onclick="StopCount" disabled="@(cts == null)">Stop</button>
|
||||
|
||||
<div>
|
||||
<img src="/grpc-logo.png" alt="gRPC logo" />
|
||||
<p>
|
||||
Incrementing count streamed from a gRPC service.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
private CancellationTokenSource? cts;
|
||||
|
||||
private async Task IncrementCount()
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
|
||||
var client = new Count.Counter.CounterClient(Channel);
|
||||
using var call = client.StartCounter(new CounterRequest() { Start = currentCount }, cancellationToken: cts.Token);
|
||||
|
||||
try
|
||||
{
|
||||
await foreach (var message in call.ResponseStream.ReadAllAsync())
|
||||
{
|
||||
currentCount = message.Count;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
|
||||
{
|
||||
// Ignore exception from cancellation
|
||||
}
|
||||
}
|
||||
|
||||
private void StopCount()
|
||||
{
|
||||
cts?.Cancel();
|
||||
cts = null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
@page "/fetchdata"
|
||||
@inject GrpcChannel Channel
|
||||
@using Google.Protobuf.WellKnownTypes
|
||||
|
||||
<h1>Weather forecast</h1>
|
||||
|
||||
<p>This component demonstrates fetching data from the server.</p>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.DateTime.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
<div>
|
||||
<img src="/grpc-logo.png" alt="gRPC logo" />
|
||||
<p>
|
||||
Data fetched from a gRPC service.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private IList<WeatherForecast>? forecasts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var client = new WeatherForecasts.WeatherForecastsClient(Channel);
|
||||
forecasts = (await client.GetWeatherForecastsAsync(new Empty())).Forecasts;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
@page "/"
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
||||
|
||||
<SurveyPrompt Title="How is Blazor working for you?" />
|
|
@ -0,0 +1,62 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Net.Client;
|
||||
using Grpc.Net.Client.Web;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Client
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
|
||||
builder.Services.AddSingleton(services =>
|
||||
{
|
||||
// Get the service address from appsettings.json
|
||||
var config = services.GetRequiredService<IConfiguration>();
|
||||
var backendUrl = config["BackendUrl"];
|
||||
|
||||
// If no address is set then fallback to the current webpage URL
|
||||
if (string.IsNullOrEmpty(backendUrl))
|
||||
{
|
||||
var navigationManager = services.GetRequiredService<NavigationManager>();
|
||||
backendUrl = navigationManager.BaseUri;
|
||||
}
|
||||
|
||||
// Create a channel with a GrpcWebHandler that is addressed to the backend server.
|
||||
//
|
||||
// GrpcWebText is used because server streaming requires it. If server streaming is not used in your app
|
||||
// then GrpcWeb is recommended because it produces smaller messages.
|
||||
var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
|
||||
|
||||
return GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpHandler = httpHandler });
|
||||
});
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
<div class="sidebar">
|
||||
<NavMenu />
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div class="top-row px-4">
|
||||
<a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
|
||||
</div>
|
||||
|
||||
<div class="content px-4">
|
||||
@Body
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,37 @@
|
|||
<div class="top-row pl-4 navbar navbar-dark">
|
||||
<a class="navbar-brand" href="">gRPC-Web in Blazor</a>
|
||||
<button class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="oi oi-home" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="counter">
|
||||
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="fetchdata">
|
||||
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
|
||||
</NavLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool collapseNavMenu = true;
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private void ToggleNavMenu()
|
||||
{
|
||||
collapseNavMenu = !collapseNavMenu;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<div class="alert alert-secondary mt-4" role="alert">
|
||||
<span class="oi oi-pencil mr-2" aria-hidden="true"></span>
|
||||
<strong>@Title</strong>
|
||||
|
||||
<span class="text-nowrap">
|
||||
Please take our
|
||||
<a target="_blank" class="font-weight-bold" href="https://go.microsoft.com/fwlink/?linkid=2109206">brief survey</a>
|
||||
</span>
|
||||
and tell us what you think.
|
||||
</div>
|
||||
|
||||
@code {
|
||||
// Demonstrates how a parent component can supply parameters
|
||||
[Parameter]
|
||||
public string? Title { get; set; }
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
@using System.Net.Http
|
||||
@using System.Threading
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.JSInterop
|
||||
@using Client
|
||||
@using Client.Shared
|
||||
@using Count
|
||||
@using Grpc.Net.Client
|
||||
@using Weather
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
// Explicit backend URL (override current site)
|
||||
"BackendUrl": null
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,86 @@
|
|||
SIL OPEN FONT LICENSE Version 1.1
|
||||
|
||||
Copyright (c) 2014 Waybury
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Waybury
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,114 @@
|
|||
[Open Iconic v1.1.1](http://useiconic.com/open)
|
||||
===========
|
||||
|
||||
### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons)
|
||||
|
||||
|
||||
|
||||
## What's in Open Iconic?
|
||||
|
||||
* 223 icons designed to be legible down to 8 pixels
|
||||
* Super-light SVG files - 61.8 for the entire set
|
||||
* SVG sprite—the modern replacement for icon fonts
|
||||
* Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats
|
||||
* Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats
|
||||
* PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px.
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
#### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections.
|
||||
|
||||
### General Usage
|
||||
|
||||
#### Using Open Iconic's SVGs
|
||||
|
||||
We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute).
|
||||
|
||||
```
|
||||
<img src="/open-iconic/svg/icon-name.svg" alt="icon name">
|
||||
```
|
||||
|
||||
#### Using Open Iconic's SVG Sprite
|
||||
|
||||
Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack.
|
||||
|
||||
Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `<svg>` *tag and a unique class name for each different icon in the* `<use>` *tag.*
|
||||
|
||||
```
|
||||
<svg class="icon">
|
||||
<use xlink:href="open-iconic.svg#account-login" class="icon-account-login"></use>
|
||||
</svg>
|
||||
```
|
||||
|
||||
Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `<svg>` tag with equal width and height dimensions.
|
||||
|
||||
```
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
```
|
||||
|
||||
Coloring icons is even easier. All you need to do is set the `fill` rule on the `<use>` tag.
|
||||
|
||||
```
|
||||
.icon-account-login {
|
||||
fill: #f00;
|
||||
}
|
||||
```
|
||||
|
||||
To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/).
|
||||
|
||||
#### Using Open Iconic's Icon Font...
|
||||
|
||||
|
||||
##### …with Bootstrap
|
||||
|
||||
You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}`
|
||||
|
||||
|
||||
```
|
||||
<link href="/open-iconic/font/css/open-iconic-bootstrap.css" rel="stylesheet">
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
<span class="oi oi-icon-name" title="icon name" aria-hidden="true"></span>
|
||||
```
|
||||
|
||||
##### …with Foundation
|
||||
|
||||
You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}`
|
||||
|
||||
```
|
||||
<link href="/open-iconic/font/css/open-iconic-foundation.css" rel="stylesheet">
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
<span class="fi-icon-name" title="icon name" aria-hidden="true"></span>
|
||||
```
|
||||
|
||||
##### …on its own
|
||||
|
||||
You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}`
|
||||
|
||||
```
|
||||
<link href="/open-iconic/font/css/open-iconic.css" rel="stylesheet">
|
||||
```
|
||||
|
||||
```
|
||||
<span class="oi" data-glyph="icon-name" title="icon name" aria-hidden="true"></span>
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
### Icons
|
||||
|
||||
All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT).
|
||||
|
||||
### Fonts
|
||||
|
||||
All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web).
|
1
examples/Blazor/Client/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css
vendored
Normal file
1
examples/Blazor/Client/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,543 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<!--
|
||||
2014-7-1: Created.
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>
|
||||
Created by FontForge 20120731 at Tue Jul 1 20:39:22 2014
|
||||
By P.J. Onori
|
||||
Created by P.J. Onori with FontForge 2.0 (http://fontforge.sf.net)
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="open-iconic" horiz-adv-x="800" >
|
||||
<font-face
|
||||
font-family="Icons"
|
||||
font-weight="400"
|
||||
font-stretch="normal"
|
||||
units-per-em="800"
|
||||
panose-1="2 0 5 3 0 0 0 0 0 0"
|
||||
ascent="800"
|
||||
descent="0"
|
||||
bbox="-0.5 -101 802 800.126"
|
||||
underline-thickness="50"
|
||||
underline-position="-100"
|
||||
unicode-range="U+E000-E0DE"
|
||||
/>
|
||||
<missing-glyph />
|
||||
<glyph glyph-name="" unicode=""
|
||||
d="M300 700h500v-700h-500v100h400v500h-400v100zM400 500l200 -150l-200 -150v100h-400v100h400v100z" />
|
||||
<glyph glyph-name="1" unicode=""
|
||||
d="M300 700h500v-700h-500v100h400v500h-400v100zM200 500v-100h400v-100h-400v-100l-200 150z" />
|
||||
<glyph glyph-name="2" unicode=""
|
||||
d="M350 700c193 0 350 -157 350 -350v-50h100l-200 -200l-200 200h100v50c0 138 -112 250 -250 250s-250 -112 -250 -250c0 193 157 350 350 350z" />
|
||||
<glyph glyph-name="3" unicode=""
|
||||
d="M450 700c193 0 350 -157 350 -350c0 138 -112 250 -250 250s-250 -112 -250 -250v-50h100l-200 -200l-200 200h100v50c0 193 157 350 350 350z" />
|
||||
<glyph glyph-name="4" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM100 500h600v-100h-600v100zM0 300h800v-100h-800v100zM100 100h600v-100h-600v100z" />
|
||||
<glyph glyph-name="5" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM0 500h600v-100h-600v100zM0 300h800v-100h-800v100zM0 100h600v-100h-600v100z" />
|
||||
<glyph glyph-name="6" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM200 500h600v-100h-600v100zM0 300h800v-100h-800v100zM200 100h600v-100h-600v100z" />
|
||||
<glyph glyph-name="7" unicode=""
|
||||
d="M400 700c75 0 146 -23 206 -59l-75 -225l-322 234c57 31 122 50 191 50zM125 588l191 -138l-310 -222c-4 24 -6 47 -6 72c0 114 49 215 125 288zM688 575c69 -72 112 -168 112 -275c0 -35 -8 -68 -16 -100h-218zM216 253l112 -347c-128 23 -232 109 -287 222zM372 100
|
||||
h372c-64 -109 -177 -185 -310 -197z" />
|
||||
<glyph glyph-name="8" unicode="" horiz-adv-x="600"
|
||||
d="M200 800h100v-500h200l-247 -300l-253 300h200v500z" />
|
||||
<glyph glyph-name="9" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM300 700v-300h-200l300 -300l300 300h-200v300h-200z" />
|
||||
<glyph glyph-name="a" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 700l-300 -300l300 -300v200h300v200h-300v200z" />
|
||||
<glyph glyph-name="b" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 700v-200h-300v-200h300v-200l300 300z" />
|
||||
<glyph glyph-name="c" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 700l-300 -300h200v-300h200v300h200z" />
|
||||
<glyph glyph-name="d" unicode=""
|
||||
d="M300 600v-200h500v-100h-500v-200l-300 247z" />
|
||||
<glyph glyph-name="e" unicode=""
|
||||
d="M500 600l300 -247l-300 -253v200h-500v100h500v200z" />
|
||||
<glyph glyph-name="f" unicode="" horiz-adv-x="600"
|
||||
d="M200 800h200v-500h200l-297 -300l-303 300h200v500z" />
|
||||
<glyph glyph-name="10" unicode=""
|
||||
d="M300 700v-200h500v-200h-500v-200l-300 297z" />
|
||||
<glyph glyph-name="11" unicode=""
|
||||
d="M500 700l300 -297l-300 -303v200h-500v200h500v200z" />
|
||||
<glyph glyph-name="12" unicode="" horiz-adv-x="600"
|
||||
d="M297 800l303 -300h-200v-500h-200v500h-200z" />
|
||||
<glyph glyph-name="13" unicode="" horiz-adv-x="600"
|
||||
d="M247 800l253 -300h-200v-500h-100v500h-200z" />
|
||||
<glyph glyph-name="14" unicode=""
|
||||
d="M400 800h100v-800h-100v800zM200 700h100v-600h-100v600zM600 600h100v-400h-100v400zM0 500h100v-200h-100v200z" />
|
||||
<glyph glyph-name="15" unicode=""
|
||||
d="M116 600l72 -72c-54 -54 -88 -126 -88 -209s34 -159 88 -213l-72 -72c-72 72 -116 175 -116 285s44 209 116 281zM684 600c72 -72 116 -171 116 -281s-44 -213 -116 -285l-72 72c54 54 88 130 88 213s-34 155 -88 209zM259 460l69 -72c-18 -18 -28 -41 -28 -69
|
||||
s10 -54 28 -72l-69 -72c-36 36 -59 89 -59 144s23 105 59 141zM541 459c36 -36 59 -85 59 -140s-23 -108 -59 -144l-69 72c18 18 28 44 28 72s-10 51 -28 69z" />
|
||||
<glyph glyph-name="16" unicode="" horiz-adv-x="400"
|
||||
d="M200 800c110 0 200 -90 200 -200s-90 -200 -200 -200s-200 90 -200 200s90 200 200 200zM100 319c31 -11 65 -19 100 -19s68 8 100 19v-319l-100 100l-100 -100v319z" />
|
||||
<glyph glyph-name="17" unicode=""
|
||||
d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 -300 -134 -300 -300c0 -66 21 -126 56 -175l419 419c-49 35 -109 56 -175 56zM644 575l-419 -419c49 -35 109 -56 175 -56c166 0 300 134 300 300
|
||||
c0 66 -21 126 -56 175z" />
|
||||
<glyph glyph-name="18" unicode=""
|
||||
d="M0 700h100v-600h700v-100h-800v700zM500 700h200v-500h-200v500zM200 500h200v-300h-200v300z" />
|
||||
<glyph glyph-name="19" unicode=""
|
||||
d="M397 800c13 1 23 -4 34 -13c2 -2 214 -254 241 -287h128v-100h-100v-366c0 -18 -16 -34 -34 -34h-532c-18 0 -34 16 -34 34v366h-100v100h128l234 281c9 11 22 18 35 19zM400 672l-144 -172h288zM250 300c-28 0 -50 -22 -50 -50v-100c0 -28 22 -50 50 -50s50 22 50 50
|
||||
v100c0 28 -22 50 -50 50zM550 300c-28 0 -50 -22 -50 -50v-100c0 -28 22 -50 50 -50s50 22 50 50v100c0 28 -22 50 -50 50z" />
|
||||
<glyph glyph-name="1a" unicode=""
|
||||
d="M9 700h682c6 0 9 -4 9 -10v-190h100v-200h-100v-191c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v582c0 6 3 9 9 9zM100 600v-400h500v400h-500z" />
|
||||
<glyph glyph-name="1b" unicode=""
|
||||
d="M9 700h682c6 0 9 -4 9 -10v-190h100v-200h-100v-191c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v582c0 6 3 9 9 9z" />
|
||||
<glyph glyph-name="1c" unicode=""
|
||||
d="M92 650c0 23 19 50 45 50h3h5h5h500c28 0 50 -22 50 -50s-22 -50 -50 -50h-50v-141c9 -17 120 -231 166 -309c16 -26 34 -61 34 -106c0 -39 -15 -77 -41 -103h-3c-26 -25 -62 -41 -100 -41h-512c-39 0 -77 15 -103 41s-41 64 -41 103c0 46 18 80 34 106
|
||||
c46 78 157 292 166 309v141h-50c-2 0 -6 -1 -8 -1c-28 0 -50 23 -50 51zM500 600h-200v-162l-6 -10s-63 -123 -119 -228h450c-56 105 -119 228 -119 228l-6 10v162z" />
|
||||
<glyph glyph-name="1d" unicode=""
|
||||
d="M400 800c110 0 200 -90 200 -200c0 -104 52 -198 134 -266c41 -34 66 -82 66 -134h-800c0 52 25 100 66 134c82 68 134 162 134 266c0 110 90 200 200 200zM300 100h200c0 -55 -45 -100 -100 -100s-100 45 -100 100z" />
|
||||
<glyph glyph-name="1e" unicode="" horiz-adv-x="600"
|
||||
d="M150 800h50l350 -250l-225 -147l225 -153l-350 -250h-50v250l-75 -75l-75 75l150 150l-150 150l75 75l75 -75v250zM250 650v-200l150 100zM250 350v-200l150 100z" />
|
||||
<glyph glyph-name="1f" unicode=""
|
||||
d="M0 800h500c110 0 200 -90 200 -200c0 -47 -17 -91 -44 -125c85 -40 144 -125 144 -225c0 -138 -112 -250 -250 -250h-550v100c55 0 100 45 100 100v400c0 55 -45 100 -100 100v100zM300 700v-200h100c55 0 100 45 100 100s-45 100 -100 100h-100zM300 400v-300h150
|
||||
c83 0 150 67 150 150s-67 150 -150 150h-150z" />
|
||||
<glyph glyph-name="20" unicode="" horiz-adv-x="600"
|
||||
d="M300 800v-300h200l-300 -500v300h-200z" />
|
||||
<glyph glyph-name="21" unicode=""
|
||||
d="M100 800h300v-300l100 100l100 -100v300h50c28 0 50 -22 50 -50v-550h-550c-28 0 -50 -22 -50 -50s22 -50 50 -50h550v-100h-550c-83 0 -150 67 -150 150v550l3 19c8 39 39 70 78 78z" />
|
||||
<glyph glyph-name="22" unicode="" horiz-adv-x="400"
|
||||
d="M0 800h400v-800l-200 200l-200 -200v800z" />
|
||||
<glyph glyph-name="23" unicode=""
|
||||
d="M0 800h800v-100h-800v100zM0 600h300v-103h203v103h297v-591c0 -6 -3 -9 -9 -9h-782c-6 0 -9 3 -9 9v591z" />
|
||||
<glyph glyph-name="24" unicode=""
|
||||
d="M300 800h200c55 0 100 -45 100 -100v-100h191c6 0 9 -3 9 -9v-241c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 -50 50v241c0 6 3 9 9 9h191v100c0 55 45 100 100 100zM300 700v-100h200v100h-200zM0 209c16 -6 32 -9 50 -9h700c18 0 34 3 50 9v-200c0 -6 -3 -9 -9 -9h-782
|
||||
c-6 0 -9 3 -9 9v200z" />
|
||||
<glyph glyph-name="25" unicode="" horiz-adv-x="600"
|
||||
d="M300 800c58 0 110 -16 147 -53s53 -89 53 -147h-100c0 39 -11 61 -25 75s-36 25 -75 25c-35 0 -55 -10 -72 -31s-28 -55 -28 -94c0 -51 20 -107 28 -175h172v-100h-178c-14 -60 -49 -127 -113 -200h491v-100h-600v122l16 12c69 69 95 121 106 166h-122v100h125
|
||||
c-8 50 -25 106 -25 175c0 58 16 114 50 156c34 43 88 69 150 69z" />
|
||||
<glyph glyph-name="26" unicode=""
|
||||
d="M34 700h4h3h4h5h700c28 0 50 -22 50 -50v-700c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 -50 50v700v2c0 20 15 42 34 48zM150 600c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50zM350 600c-28 0 -50 -22 -50 -50s22 -50 50 -50h300c28 0 50 22 50 50
|
||||
s-22 50 -50 50h-300zM100 400v-400h600v400h-600z" />
|
||||
<glyph glyph-name="27" unicode=""
|
||||
d="M744 797l6 -3l44 -44c4 -4 3 -8 0 -12l-266 -375l-15 -13l-25 -12c-23 72 -78 127 -150 150l12 25l13 15l375 266zM266 400c74 0 134 -60 134 -134c0 -147 -119 -266 -266 -266c-48 0 -95 12 -134 34c80 46 134 133 134 232c0 74 58 134 132 134z" />
|
||||
<glyph glyph-name="28" unicode=""
|
||||
d="M9 451c0 23 19 50 46 50c8 0 19 -3 26 -7l131 -66l29 22c-79 81 -1 250 118 250s197 -167 119 -250l28 -22l131 66c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-115 -56c9 -16 19 -33 25 -50h68c28 0 50 -22 50 -50s-22 -50 -50 -50h-50
|
||||
c0 -23 -2 -45 -6 -66l78 -40c21 -5 37 -28 37 -49c0 -28 -22 -50 -50 -50c-10 0 -23 5 -31 11l-65 35c-24 -46 -62 -86 -103 -110c-35 19 -60 45 -60 72v135v4v5v6v5v5v87c0 28 -22 50 -50 50c-24 0 -45 -17 -50 -40c1 -3 1 -8 1 -11s0 -8 -1 -11v-82v-4v-5v-144
|
||||
c0 -28 -24 -53 -59 -72c-41 25 -79 64 -103 110l-66 -35c-8 -6 -21 -11 -31 -11c-28 0 -50 22 -50 50c0 21 16 44 37 49l78 40c-4 21 -6 43 -6 66h-50h-5c-28 0 -50 22 -50 50c0 26 22 50 50 50h5h69c6 17 16 34 25 50l-116 56c-16 7 -28 27 -28 45z" />
|
||||
<glyph glyph-name="29" unicode=""
|
||||
d="M600 700h91c6 0 9 -3 9 -9v-582c0 -6 -3 -9 -9 -9h-91v600zM210 503l290 147v-500l-250 125v-3c-15 0 -25 -8 -28 -22l75 -178c11 -25 0 -58 -25 -69s-58 0 -69 25l-103 272h-91c-6 0 -9 3 -9 9v182c0 6 3 9 9 9h182z" />
|
||||
<glyph glyph-name="2a" unicode=""
|
||||
d="M9 800h682c6 0 9 -3 9 -9v-782c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v782c0 6 3 9 9 9zM100 700v-200h500v200h-500zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400v-300h100v300h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100z" />
|
||||
<glyph glyph-name="2b" unicode=""
|
||||
d="M0 800h700v-200h-700v200zM0 500h700v-491c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v491zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100z" />
|
||||
<glyph glyph-name="2c" unicode=""
|
||||
d="M409 800h182c6 0 10 -4 12 -9l94 -182c2 -5 6 -9 12 -9h82c6 0 9 -3 9 -9v-582c0 -6 -3 -9 -9 -9h-782c-6 0 -9 3 -9 9v441c0 83 67 150 150 150h141c6 0 10 4 12 9l94 182c2 5 6 9 12 9zM150 500c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z
|
||||
M500 500c-110 0 -200 -90 -200 -200s90 -200 200 -200s200 90 200 200s-90 200 -200 200zM500 400c55 0 100 -45 100 -100s-45 -100 -100 -100s-100 45 -100 100s45 100 100 100z" />
|
||||
<glyph glyph-name="2d" unicode=""
|
||||
d="M0 600h800l-400 -400z" />
|
||||
<glyph glyph-name="2e" unicode="" horiz-adv-x="400"
|
||||
d="M400 800v-800l-400 400z" />
|
||||
<glyph glyph-name="2f" unicode="" horiz-adv-x="400"
|
||||
d="M0 800l400 -400l-400 -400v800z" />
|
||||
<glyph glyph-name="30" unicode=""
|
||||
d="M400 600l400 -400h-800z" />
|
||||
<glyph glyph-name="31" unicode=""
|
||||
d="M0 550c0 23 20 50 46 50h3h5h4h200c17 0 37 -13 44 -28l38 -72h444c14 0 19 -12 15 -25l-81 -250c-4 -13 -21 -25 -35 -25h-350c-14 0 -30 12 -34 25c-27 83 -54 167 -81 250l-10 25h-150c-2 0 -5 -1 -7 -1c-28 0 -51 23 -51 51zM358 100c28 0 50 -22 50 -50
|
||||
s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM658 100c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50z" />
|
||||
<glyph glyph-name="32" unicode=""
|
||||
d="M0 700h500v-100h-300v-300h-100l-100 -100v500zM300 500h500v-500l-100 100h-400v400z" />
|
||||
<glyph glyph-name="33" unicode=""
|
||||
d="M641 700l143 -141l-493 -493c-71 76 -146 148 -219 222l-72 71l141 141c50 -51 101 -101 153 -150c116 117 234 231 347 350z" />
|
||||
<glyph glyph-name="34" unicode=""
|
||||
d="M150 600l250 -250l250 250l150 -150l-400 -400l-400 400z" />
|
||||
<glyph glyph-name="35" unicode="" horiz-adv-x="600"
|
||||
d="M400 800l150 -150l-250 -250l250 -250l-150 -150l-400 400z" />
|
||||
<glyph glyph-name="36" unicode="" horiz-adv-x="600"
|
||||
d="M150 800l400 -400l-400 -400l-150 150l250 250l-250 250z" />
|
||||
<glyph glyph-name="37" unicode=""
|
||||
d="M400 600l400 -400l-150 -150l-250 250l-250 -250l-150 150z" />
|
||||
<glyph glyph-name="38" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM600 622l-250 -250l-100 100l-72 -72l172 -172l322 322z" />
|
||||
<glyph glyph-name="39" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM250 622l-72 -72l150 -150l-150 -150l72 -72l150 150l150 -150l72 72l-150 150l150 150l-72 72l-150 -150z" />
|
||||
<glyph glyph-name="3a" unicode=""
|
||||
d="M350 800c28 0 50 -22 50 -50v-50h75c14 0 25 -11 25 -25v-75h-300v75c0 14 11 25 25 25h75v50c0 28 22 50 50 50zM25 700h75v-200h500v200h75c14 0 25 -11 25 -25v-650c0 -14 -11 -25 -25 -25h-650c-14 0 -25 11 -25 25v650c0 14 11 25 25 25z" />
|
||||
<glyph glyph-name="3b" unicode=""
|
||||
d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 -300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM350 600h100v-181c23 -24 47 -47 72 -69l-72 -72c-27 30 -55 59 -84 88l-16 12
|
||||
v222z" />
|
||||
<glyph glyph-name="3c" unicode=""
|
||||
d="M450 800c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -18 -3 -34 -9 -50h-191v50c0 83 -67 150 -150 150s-150 -67 -150 -150v-50h-272c-17 30 -28 63 -28 100c0 110 90 200 200 200c23 114 129 200 250 200zM434 400h3h4c3 0 6 1 9 1c28 0 50 -22 50 -50v-1
|
||||
v-150h150l-200 -200l-200 200h150v150v2c0 20 15 42 34 48z" />
|
||||
<glyph glyph-name="3d" unicode=""
|
||||
d="M450 800c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -18 -3 -34 -9 -50h-141l-200 200l-200 -200h-222c-17 30 -28 63 -28 100c0 110 90 200 200 200c23 114 129 200 250 200zM450 350l250 -250h-200v-50c0 -28 -22 -50 -50 -50s-50 22 -50 50v50h-200z" />
|
||||
<glyph glyph-name="3e" unicode=""
|
||||
d="M450 700c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -83 -67 -150 -150 -150h-450c-110 0 -200 90 -200 200s90 200 200 200c23 114 129 200 250 200z" />
|
||||
<glyph glyph-name="3f" unicode=""
|
||||
d="M250 800c82 0 154 -40 200 -100c-143 0 -270 -85 -325 -209c-36 -10 -70 -25 -100 -47c-16 33 -25 67 -25 106c0 138 112 250 250 250zM450 600c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -83 -67 -150 -150 -150h-450c-110 0 -200 90 -200 200
|
||||
s90 200 200 200c23 114 129 200 250 200z" />
|
||||
<glyph glyph-name="40" unicode=""
|
||||
d="M500 700h100l-300 -600h-100zM100 600h100l-100 -200l100 -200h-100l-100 200zM600 600h100l100 -200l-100 -200h-100l100 200z" />
|
||||
<glyph glyph-name="41" unicode=""
|
||||
d="M350 800h100l50 -119l28 -12l119 50l72 -72l-50 -119l12 -28l119 -50v-100l-119 -50l-12 -28l50 -119l-72 -72l-119 50l-28 -12l-50 -119h-100l-50 119l-28 12l-119 -50l-72 72l50 119l-12 28l-119 50v100l119 50l12 28l-50 119l72 72l119 -50l28 12zM400 550
|
||||
c-83 0 -150 -67 -150 -150s67 -150 150 -150s150 67 150 150s-67 150 -150 150z" />
|
||||
<glyph glyph-name="42" unicode=""
|
||||
d="M0 800h800v-200h-800v200zM200 500h400l-200 -200zM0 100h800v-100h-800v100z" />
|
||||
<glyph glyph-name="43" unicode=""
|
||||
d="M0 800h100v-800h-100v800zM600 800h200v-800h-200v800zM500 600v-400l-200 200z" />
|
||||
<glyph glyph-name="44" unicode=""
|
||||
d="M0 800h200v-800h-200v800zM700 800h100v-800h-100v800zM300 600l200 -200l-200 -200v400z" />
|
||||
<glyph glyph-name="45" unicode=""
|
||||
d="M0 800h800v-100h-800v100zM400 500l200 -200h-400zM0 200h800v-200h-800v200z" />
|
||||
<glyph glyph-name="46" unicode=""
|
||||
d="M150 700c83 0 150 -67 150 -150v-50h100v50c0 83 67 150 150 150s150 -67 150 -150s-67 -150 -150 -150h-50v-100h50c83 0 150 -67 150 -150s-67 -150 -150 -150s-150 67 -150 150v50h-100v-50c0 -83 -67 -150 -150 -150s-150 67 -150 150s67 150 150 150h50v100h-50
|
||||
c-83 0 -150 67 -150 150s67 150 150 150zM150 600c-28 0 -50 -22 -50 -50s22 -50 50 -50h50v50c0 28 -22 50 -50 50zM550 600c-28 0 -50 -22 -50 -50v-50h50c28 0 50 22 50 50s-22 50 -50 50zM300 400v-100h100v100h-100zM150 200c-28 0 -50 -22 -50 -50s22 -50 50 -50
|
||||
s50 22 50 50v50h-50zM500 200v-50c0 -28 22 -50 50 -50s50 22 50 50s-22 50 -50 50h-50z" />
|
||||
<glyph glyph-name="47" unicode=""
|
||||
d="M0 791c0 5 4 9 9 9h782c6 0 9 -4 9 -10v-790l-200 200h-591c-6 0 -9 3 -9 9v582z" />
|
||||
<glyph glyph-name="48" unicode=""
|
||||
d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 -300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM600 600l-100 -300l-300 -100l100 300zM400 450c-28 0 -50 -22 -50 -50
|
||||
s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
|
||||
<glyph glyph-name="49" unicode=""
|
||||
d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700v-600c166 0 300 134 300 300s-134 300 -300 300z" />
|
||||
<glyph glyph-name="4a" unicode=""
|
||||
d="M0 800h800v-100h-800v100zM0 600h500v-100h-500v100zM0 300h800v-100h-800v100zM0 100h600v-100h-600v100zM750 100c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50z" />
|
||||
<glyph glyph-name="4b" unicode=""
|
||||
d="M25 700h750c14 0 25 -11 25 -25v-75h-800v75c0 14 11 25 25 25zM0 500h800v-375c0 -14 -11 -25 -25 -25h-750c-14 0 -25 11 -25 25v375zM100 300v-100h100v100h-100zM300 300v-100h100v100h-100z" />
|
||||
<glyph glyph-name="4c" unicode=""
|
||||
d="M100 800h100v-100h450l100 100l50 -50l-100 -100v-450h100v-100h-100v-100h-100v100h-500v500h-100v100h100v100zM200 600v-350l350 350h-350zM600 550l-350 -350h350v350z" />
|
||||
<glyph glyph-name="4d" unicode=""
|
||||
d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 -300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM400 600c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50z
|
||||
M200 452c0 20 15 42 34 48h3h3h8c12 0 28 -7 36 -16l91 -90l25 6c55 0 100 -45 100 -100s-45 -100 -100 -100s-100 45 -100 100l6 25l-90 91c-9 8 -16 24 -16 36zM550 500c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50z" />
|
||||
<glyph glyph-name="4e" unicode=""
|
||||
d="M300 800h200v-300h200l-300 -300l-300 300h200v300zM0 100h800v-100h-800v100z" />
|
||||
<glyph glyph-name="4f" unicode=""
|
||||
d="M0 800h800v-100h-800v100zM400 600l300 -300h-200v-300h-200v300h-200z" />
|
||||
<glyph glyph-name="50" unicode=""
|
||||
d="M200 700h600v-600h-600l-200 300zM350 622l-72 -72l150 -150l-150 -150l72 -72l150 150l150 -150l72 72l-150 150l150 150l-72 72l-150 -150z" />
|
||||
<glyph glyph-name="51" unicode=""
|
||||
d="M400 700c220 0 400 -180 400 -400h-100c0 166 -134 300 -300 300s-300 -134 -300 -300h-100c0 220 180 400 400 400zM341 491l59 -88l59 88c81 -25 141 -101 141 -191c0 -110 -90 -200 -200 -200s-200 90 -200 200c0 90 60 166 141 191z" />
|
||||
<glyph glyph-name="52" unicode=""
|
||||
d="M0 800h300v-400h400v-400h-700v800zM400 800l300 -300h-300v300zM100 600v-100h100v100h-100zM100 400v-100h100v100h-100zM100 200v-100h400v100h-400z" />
|
||||
<glyph glyph-name="53" unicode="" horiz-adv-x="600"
|
||||
d="M200 700h100v-100h75c30 0 58 -6 81 -22s44 -44 44 -78v-100h-100v94c-4 3 -13 6 -25 6h-250c-14 0 -25 -11 -25 -25v-50c0 -15 20 -40 34 -44l257 -65c66 -16 109 -73 109 -141v-50c0 -68 -57 -125 -125 -125h-75v-100h-100v100h-75c-30 0 -58 6 -81 22s-44 44 -44 78
|
||||
v100h100v-94c4 -3 13 -6 25 -6h250c14 0 25 11 25 25v50c0 15 -20 40 -34 44l-257 65c-66 16 -109 73 -109 141v50c0 68 57 125 125 125h75v100z" />
|
||||
<glyph glyph-name="54" unicode=""
|
||||
d="M0 700h300v-300l-300 -300v600zM500 700h300v-300l-300 -300v600z" />
|
||||
<glyph glyph-name="55" unicode=""
|
||||
d="M300 700v-600h-300v300zM800 700v-600h-300v300z" />
|
||||
<glyph glyph-name="56" unicode=""
|
||||
d="M300 700v-100c-111 0 -200 -89 -200 -200h200v-300h-300v300c0 165 135 300 300 300zM800 700v-100c-111 0 -200 -89 -200 -200h200v-300h-300v300c0 165 135 300 300 300z" />
|
||||
<glyph glyph-name="57" unicode=""
|
||||
d="M0 700h300v-300c0 -165 -135 -300 -300 -300v100c111 0 200 89 200 200h-200v300zM500 700h300v-300c0 -165 -135 -300 -300 -300v100c111 0 200 89 200 200h-200v300z" />
|
||||
<glyph glyph-name="58" unicode="" horiz-adv-x="600"
|
||||
d="M300 800l34 -34c11 -11 266 -270 266 -488c0 -165 -135 -300 -300 -300s-300 135 -300 300c0 218 255 477 266 488zM150 328c-28 0 -50 -22 -50 -50c0 -110 90 -200 200 -200c28 0 50 22 50 50s-22 50 -50 50c-55 0 -100 45 -100 100c0 28 -22 50 -50 50z" />
|
||||
<glyph glyph-name="59" unicode=""
|
||||
d="M400 800l400 -500h-800zM0 200h800v-200h-800v200z" />
|
||||
<glyph glyph-name="5a" unicode="" horiz-adv-x="600"
|
||||
d="M300 800l300 -300h-600zM0 300h600l-300 -300z" />
|
||||
<glyph glyph-name="5b" unicode=""
|
||||
d="M0 500h200v-200h-200v200zM300 500h200v-200h-200v200zM600 500h200v-200h-200v200z" />
|
||||
<glyph glyph-name="5c" unicode=""
|
||||
d="M0 700h800v-100l-400 -200l-400 200v100zM0 500l400 -200l400 200v-400h-800v400z" />
|
||||
<glyph glyph-name="5d" unicode=""
|
||||
d="M400 800l400 -200v-600h-800v600zM400 688l-300 -150v-188l300 -150l300 150v188zM200 500h400v-100l-200 -100l-200 100v100z" />
|
||||
<glyph glyph-name="5e" unicode=""
|
||||
d="M600 700c69 0 134 -19 191 -50l-16 -106c-49 35 -109 56 -175 56c-131 0 -240 -84 -281 -200h331l-16 -100h-334c0 -36 8 -68 19 -100h297l-16 -100h-222c55 -61 133 -100 222 -100c78 0 147 30 200 78v-122c-59 -35 -127 -56 -200 -56c-147 0 -274 82 -344 200h-256
|
||||
l19 100h197c-8 32 -16 66 -16 100h-200l25 100h191c45 172 198 300 384 300z" />
|
||||
<glyph glyph-name="5f" unicode=""
|
||||
d="M0 700h700v-100h-700v100zM0 500h500v-100h-500v100zM0 300h800v-100h-800v100zM0 100h100v-100h-100v100zM200 100h100v-100h-100v100zM400 100h100v-100h-100v100z" />
|
||||
<glyph glyph-name="60" unicode=""
|
||||
d="M0 800h800v-100h-800v100zM200 600h400l-200 -200zM0 200h800v-200h-800v200z" />
|
||||
<glyph glyph-name="61" unicode=""
|
||||
d="M0 800h100v-800h-100v800zM600 800h200v-800h-200v800zM200 600l200 -200l-200 -200v400z" />
|
||||
<glyph glyph-name="62" unicode=""
|
||||
d="M0 800h200v-800h-200v800zM700 800h100v-800h-100v800zM600 600v-400l-200 200z" />
|
||||
<glyph glyph-name="63" unicode=""
|
||||
d="M0 800h800v-200h-800v200zM400 400l200 -200h-400zM0 100h800v-100h-800v100z" />
|
||||
<glyph glyph-name="64" unicode=""
|
||||
d="M0 800h200v-100h-100v-600h600v100h100v-200h-800v800zM400 800h400v-400l-150 150l-250 -250l-100 100l250 250z" />
|
||||
<glyph glyph-name="65" unicode=""
|
||||
d="M403 700c247 0 397 -300 397 -300s-150 -300 -397 -300c-253 0 -403 300 -403 300s150 300 403 300zM400 600c-110 0 -200 -90 -200 -200s90 -200 200 -200s200 90 200 200s-90 200 -200 200zM400 500c10 0 19 -3 28 -6c-16 -8 -28 -24 -28 -44c0 -28 22 -50 50 -50
|
||||
c20 0 36 12 44 28c3 -9 6 -18 6 -28c0 -55 -45 -100 -100 -100s-100 45 -100 100s45 100 100 100z" />
|
||||
<glyph glyph-name="66" unicode="" horiz-adv-x="900"
|
||||
d="M331 700h3h3c3 1 7 1 10 1c12 0 29 -8 37 -17l94 -93l66 65c57 57 155 57 212 0c58 -58 58 -154 0 -212l-65 -66l93 -94c10 -8 18 -25 18 -38c0 -28 -22 -50 -50 -50c-13 0 -32 9 -40 20l-62 65l-381 -381h-269v272l375 381l-63 63c-9 8 -16 24 -16 36c0 20 16 42 35 48z
|
||||
M447 481l-313 -315l128 -132l316 316z" />
|
||||
<glyph glyph-name="67" unicode=""
|
||||
d="M0 800h300v-400h400v-400h-700v800zM400 800l300 -300h-300v300z" />
|
||||
<glyph glyph-name="68" unicode=""
|
||||
d="M200 800c0 0 200 -100 200 -300s-298 -302 -200 -500c0 0 -200 100 -200 300s300 300 200 500zM500 500c0 0 200 -100 200 -300c0 -150 -60 -200 -100 -200h-300c0 200 300 300 200 500z" />
|
||||
<glyph glyph-name="69" unicode=""
|
||||
d="M0 800h100v-800h-100v800zM200 800h300v-100h300l-200 -203l200 -197h-400v100h-200v400z" />
|
||||
<glyph glyph-name="6a" unicode="" horiz-adv-x="400"
|
||||
d="M150 800h150l-100 -200h200l-150 -300h150l-300 -300l-100 300h134l66 200h-200z" />
|
||||
<glyph glyph-name="6b" unicode=""
|
||||
d="M0 800h300v-100h500v-100h-800v200zM0 500h800v-450c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 -50 50v450z" />
|
||||
<glyph glyph-name="6c" unicode=""
|
||||
d="M150 800c83 0 150 -67 150 -150c0 -66 -41 -121 -100 -141v-118c15 5 33 9 50 9h200c28 0 50 22 50 50v59c-59 20 -100 75 -100 141c0 83 67 150 150 150s150 -67 150 -150c0 -66 -41 -121 -100 -141v-59c0 -82 -68 -150 -150 -150h-200c-14 0 -25 -7 -34 -16
|
||||
c50 -24 84 -74 84 -134c0 -83 -67 -150 -150 -150s-150 67 -150 150c0 66 41 121 100 141v218c-59 20 -100 75 -100 141c0 83 67 150 150 150z" />
|
||||
<glyph glyph-name="6d" unicode=""
|
||||
d="M0 800h400l-150 -150l150 -150l-100 -100l-150 150l-150 -150v400zM500 400l150 -150l150 150v-400h-400l150 150l-150 150z" />
|
||||
<glyph glyph-name="6e" unicode=""
|
||||
d="M100 800l150 -150l150 150v-400h-400l150 150l-150 150zM400 400h400l-150 -150l150 -150l-100 -100l-150 150l-150 -150v400z" />
|
||||
<glyph glyph-name="6f" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 700c-56 0 -108 -17 -153 -44l22 -19c33 -18 13 -48 -13 -59c-30 -13 -77 10 -65 -41c13 -55 -27 -3 -47 -15c-42 -26 49 -152 31 -156l-59 34c-8 0 -13 -5 -16 -10
|
||||
c1 -30 10 -57 19 -84c28 -11 77 -2 100 -25c47 -28 97 -115 75 -159c34 -13 68 -22 106 -22c101 0 193 48 247 125c3 24 -8 44 -50 44c-69 0 -156 13 -153 97c2 46 101 108 66 143c-30 30 12 39 12 66c0 37 -65 32 -69 50s20 36 41 56c-30 10 -60 19 -94 19zM631 591
|
||||
c-38 -11 -94 -35 -87 -53c6 -15 52 -1 65 -13c11 -10 16 -59 44 -31l22 22v3c-11 26 -26 50 -44 72z" />
|
||||
<glyph glyph-name="70" unicode=""
|
||||
d="M703 800l97 -100l-400 -400l-100 100l-200 -203l-100 100l300 303l100 -100zM0 100h800v-100h-800v100z" />
|
||||
<glyph glyph-name="71" unicode=""
|
||||
d="M0 700h100v-100h-100v100zM200 700h100v-100h-100v100zM400 700h100v-100h-100v100zM600 700h100v-100h-100v100zM0 500h100v-100h-100v100zM200 500h100v-100h-100v100zM400 500h100v-100h-100v100zM600 500h100v-100h-100v100zM0 300h100v-100h-100v100zM200 300h100
|
||||
v-100h-100v100zM400 300h100v-100h-100v100zM600 300h100v-100h-100v100zM0 100h100v-100h-100v100zM200 100h100v-100h-100v100zM400 100h100v-100h-100v100zM600 100h100v-100h-100v100z" />
|
||||
<glyph glyph-name="72" unicode=""
|
||||
d="M0 800h200v-200h-200v200zM300 800h200v-200h-200v200zM600 800h200v-200h-200v200zM0 500h200v-200h-200v200zM300 500h200v-200h-200v200zM600 500h200v-200h-200v200zM0 200h200v-200h-200v200zM300 200h200v-200h-200v200zM600 200h200v-200h-200v200z" />
|
||||
<glyph glyph-name="73" unicode=""
|
||||
d="M0 800h300v-300h-300v300zM500 800h300v-300h-300v300zM0 300h300v-300h-300v300zM500 300h300v-300h-300v300z" />
|
||||
<glyph glyph-name="74" unicode=""
|
||||
d="M19 800h662c11 0 19 -8 19 -19v-331c0 -28 -22 -50 -50 -50h-600c-28 0 -50 22 -50 50v331c0 11 8 19 19 19zM0 309c16 -6 32 -9 50 -9h600c18 0 34 3 50 9v-290c0 -11 -8 -19 -19 -19h-662c-11 0 -19 8 -19 19v290zM550 200c-28 0 -50 -22 -50 -50s22 -50 50 -50
|
||||
s50 22 50 50s-22 50 -50 50z" />
|
||||
<glyph glyph-name="75" unicode=""
|
||||
d="M0 700h300v-100h-50c-28 0 -50 -22 -50 -50v-150h300v150c0 28 -22 50 -50 50h-50v100h300v-100h-50c-28 0 -50 -22 -50 -50v-400c0 -28 22 -50 50 -50h50v-100h-300v100h50c28 0 50 22 50 50v150h-300v-150c0 -28 22 -50 50 -50h50v-100h-300v100h50c28 0 50 22 50 50
|
||||
v400c0 28 -22 50 -50 50h-50v100z" />
|
||||
<glyph glyph-name="76" unicode=""
|
||||
d="M400 700c165 0 300 -135 300 -300v-100h50c28 0 50 -22 50 -50v-200c0 -28 -22 -50 -50 -50h-100c-28 0 -50 22 -50 50v350c0 111 -89 200 -200 200s-200 -89 -200 -200v-350c0 -28 -22 -50 -50 -50h-100c-28 0 -50 22 -50 50v200c0 28 22 50 50 50h50v100
|
||||
c0 165 135 300 300 300z" />
|
||||
<glyph glyph-name="77" unicode=""
|
||||
d="M0 500c0 109 91 200 200 200s200 -91 200 -200c0 109 91 200 200 200s200 -91 200 -200c0 -55 -23 -105 -59 -141l-341 -340l-341 340c-36 36 -59 86 -59 141z" />
|
||||
<glyph glyph-name="78" unicode=""
|
||||
d="M400 700l400 -300l-100 3v-403h-200v200h-200v-200h-200v400h-100z" />
|
||||
<glyph glyph-name="79" unicode=""
|
||||
d="M0 800h800v-800h-800v800zM100 700v-300l100 100l400 -400h100v100l-200 200l100 100l100 -100v300h-600z" />
|
||||
<glyph glyph-name="7a" unicode=""
|
||||
d="M19 800h762c11 0 19 -8 19 -19v-762c0 -11 -8 -19 -19 -19h-762c-11 0 -19 8 -19 19v762c0 11 8 19 19 19zM100 600v-300h100l100 -100h200l100 100h100v300h-600z" />
|
||||
<glyph glyph-name="7b" unicode=""
|
||||
d="M200 600c80 0 142 -56 200 -122c58 66 119 122 200 122c131 0 200 -101 200 -200s-69 -200 -200 -200c-81 0 -142 56 -200 122c-58 -66 -121 -122 -200 -122c-131 0 -200 101 -200 200s69 200 200 200zM200 500c-74 0 -100 -54 -100 -100s26 -100 100 -100
|
||||
c42 0 88 47 134 100c-46 53 -92 100 -134 100zM600 500c-43 0 -88 -47 -134 -100c46 -53 91 -100 134 -100c74 0 100 54 100 100s-26 100 -100 100z" />
|
||||
<glyph glyph-name="7c" unicode="" horiz-adv-x="400"
|
||||
d="M300 800c55 0 100 -45 100 -100s-45 -100 -100 -100s-100 45 -100 100s45 100 100 100zM150 550c83 0 150 -69 150 -150c0 -66 -100 -214 -100 -250c0 -28 22 -50 50 -50s50 22 50 50h100c0 -83 -67 -150 -150 -150s-150 64 -150 150s100 222 100 250s-22 50 -50 50
|
||||
s-50 -22 -50 -50h-100c0 83 67 150 150 150z" />
|
||||
<glyph glyph-name="7d" unicode=""
|
||||
d="M200 800h500v-100h-122c-77 -197 -156 -392 -234 -588l-6 -12h162v-100h-500v100h122c77 197 156 392 234 588l7 12h-163v100z" />
|
||||
<glyph glyph-name="7e" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM0 500h800v-100h-800v100zM0 300h800v-100h-800v100zM100 100h600v-100h-600v100z" />
|
||||
<glyph glyph-name="7f" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM0 500h800v-100h-800v100zM0 300h800v-100h-800v100zM0 100h600v-100h-600v100z" />
|
||||
<glyph glyph-name="80" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM0 500h800v-100h-800v100zM0 300h800v-100h-800v100zM200 100h600v-100h-600v100z" />
|
||||
<glyph glyph-name="81" unicode=""
|
||||
d="M550 800c138 0 250 -112 250 -250s-112 -250 -250 -250c-16 0 -32 0 -47 3l-3 -3v-100h-200v-200h-300v200l303 303c-3 15 -3 31 -3 47c0 138 112 250 250 250zM600 700c-55 0 -100 -45 -100 -100s45 -100 100 -100s100 45 100 100s-45 100 -100 100z" />
|
||||
<glyph glyph-name="82" unicode=""
|
||||
d="M134 600h3h4h4h5h500c28 0 50 -22 50 -50v-350h100v-150c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 -50 50v150h100v350v2c0 20 15 42 34 48zM200 500v-300h100v-100h200v100h100v300h-400z" />
|
||||
<glyph glyph-name="83" unicode=""
|
||||
d="M0 800h400v-400h-400v400zM500 600h100v-400h-400v100h300v300zM700 400h100v-400h-400v100h300v300z" />
|
||||
<glyph glyph-name="84" unicode="" horiz-adv-x="600"
|
||||
d="M337 694c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-300 -150c-8 -6 -21 -11 -31 -11c-28 0 -50 22 -50 50c0 21 16 44 37 49zM437 544c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-400 -200c-8 -6 -21 -11 -31 -11c-28 0 -50 22 -50 50
|
||||
c0 21 16 44 37 49zM437 344c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-106 -56c24 -4 43 -26 43 -50c0 -28 -23 -51 -51 -51c-2 0 -6 1 -8 1h-200c-26 1 -48 24 -48 50c0 16 12 36 26 44zM151 -50c0 23 20 50 46 50h3h4h5h100c28 0 50 -22 50 -50
|
||||
s-22 -50 -50 -50h-100c-2 0 -6 -1 -8 -1c-28 0 -50 23 -50 51z" />
|
||||
<glyph glyph-name="85" unicode=""
|
||||
d="M199 800h100v-200h-200v100h100v100zM586 797h1c18 1 38 1 56 -3c36 -8 69 -26 97 -54c78 -78 78 -203 0 -281l-150 -150c-8 -13 -28 -24 -43 -24c-28 0 -50 22 -50 50c0 15 11 35 24 43l150 150c40 40 39 105 0 144c-41 41 -110 34 -144 0l-44 -44
|
||||
c-8 -13 -27 -24 -42 -24c-28 0 -50 22 -50 50c0 15 11 35 24 43l43 44c32 33 72 53 128 56zM208 490c4 5 14 16 22 16h3c2 0 6 1 8 1c28 0 50 -22 50 -50c0 -11 -6 -27 -14 -35l-150 -150c-40 -40 -39 -105 0 -144c41 -41 110 -34 144 0l44 44c8 13 27 24 42 24
|
||||
c28 0 50 -22 50 -50c0 -15 -11 -35 -24 -43l-43 -44c-22 -22 -48 -37 -75 -47c-70 -25 -151 -9 -207 47c-78 78 -78 203 0 281zM499 200h200v-100h-100v-100h-100v200z" />
|
||||
<glyph glyph-name="86" unicode=""
|
||||
d="M586 797c18 1 39 1 57 -3c36 -8 69 -26 97 -54c78 -78 78 -203 0 -281l-150 -150c-62 -62 -132 -81 -182 -78s-69 17 -84 25s-26 27 -26 44c0 28 22 51 50 51c8 0 19 -3 26 -7c0 0 15 -11 41 -13s62 3 106 47l150 150c40 40 39 105 0 144c-41 41 -110 34 -144 0
|
||||
c-8 -13 -28 -24 -43 -24c-28 0 -50 22 -50 50c0 15 11 35 24 43c32 33 72 53 128 56zM386 566c50 -2 64 -17 85 -22s37 -28 37 -49c0 -28 -22 -50 -50 -50c-10 0 -23 5 -31 11c0 0 -19 9 -47 10s-63 -4 -103 -44l-150 -150c-40 -40 -39 -105 0 -144c41 -41 110 -34 144 0
|
||||
c8 13 27 24 42 24c28 0 50 -22 50 -50c0 -15 -10 -35 -23 -43c-22 -22 -48 -37 -75 -47c-70 -25 -151 -9 -207 47c-78 78 -78 203 0 281l150 150c60 60 128 78 178 76z" />
|
||||
<glyph glyph-name="87" unicode=""
|
||||
d="M0 700h300v-300h-300v300zM400 700h400v-100h-400v100zM400 500h300v-100h-300v100zM0 300h300v-300h-300v300zM400 300h400v-100h-400v100zM400 100h300v-100h-300v100z" />
|
||||
<glyph glyph-name="88" unicode=""
|
||||
d="M50 700c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM200 700h600v-100h-600v100zM50 500c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM200 500h600v-100h-600v100zM50 300c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50
|
||||
s22 50 50 50zM200 300h600v-100h-600v100zM50 100c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM200 100h600v-100h-600v100z" />
|
||||
<glyph glyph-name="89" unicode=""
|
||||
d="M800 800l-400 -800l-100 300l-300 100z" />
|
||||
<glyph glyph-name="8a" unicode="" horiz-adv-x="600"
|
||||
d="M300 700c110 0 200 -90 200 -200v-100h100v-400h-600v400h100v100c0 110 90 200 200 200zM300 600c-56 0 -100 -44 -100 -100v-100h200v100c0 56 -44 100 -100 100z" />
|
||||
<glyph glyph-name="8b" unicode="" horiz-adv-x="600"
|
||||
d="M300 800c110 0 200 -90 200 -200v-200h100v-400h-600v400h400v200c0 56 -44 100 -100 100s-100 -44 -100 -100h-100c0 110 90 200 200 200z" />
|
||||
<glyph glyph-name="8c" unicode=""
|
||||
d="M400 700v-100c-111 0 -200 -89 -200 -200h100l-150 -200l-150 200h100c0 165 135 300 300 300zM650 600l150 -200h-100c0 -165 -135 -300 -300 -300v100c111 0 200 89 200 200h-100z" />
|
||||
<glyph glyph-name="8d" unicode=""
|
||||
d="M100 800h600v-300h100l-150 -250l-150 250h100v200h-400v-100h-100v200zM150 550l150 -250h-100v-200h400v100h100v-200h-600v300h-100z" />
|
||||
<glyph glyph-name="8e" unicode=""
|
||||
d="M600 700l200 -150l-200 -150v100h-500v-100h-100v100c0 55 45 100 100 100h500v100zM200 300v-100h500v100h100v-100c0 -55 -45 -100 -100 -100h-500v-100l-200 150z" />
|
||||
<glyph glyph-name="8f" unicode="" horiz-adv-x="900"
|
||||
d="M350 800c193 0 350 -157 350 -350c0 -60 -17 -117 -44 -166c5 -3 12 -8 16 -12l100 -100c16 -16 30 -49 30 -72c0 -56 -46 -102 -102 -102c-23 0 -56 14 -72 30l-100 100c-4 3 -9 9 -12 13c-49 -26 -107 -41 -166 -41c-193 0 -350 157 -350 350s157 350 350 350zM350 200
|
||||
c142 0 250 108 250 250c0 139 -111 250 -250 250s-250 -111 -250 -250s111 -250 250 -250z" />
|
||||
<glyph glyph-name="90" unicode="" horiz-adv-x="600"
|
||||
d="M300 800c166 0 300 -134 300 -300c0 -200 -300 -500 -300 -500s-300 300 -300 500c0 166 134 300 300 300zM300 700c-110 0 -200 -90 -200 -200s90 -200 200 -200s200 90 200 200s-90 200 -200 200z" />
|
||||
<glyph glyph-name="91" unicode="" horiz-adv-x="900"
|
||||
d="M0 800h800v-541c1 -3 1 -8 1 -11s0 -7 -1 -10v-238h-800v800zM495 250c0 26 22 50 50 50h5h150v400h-600v-600h600v100h-150h-5c-28 0 -50 22 -50 50zM350 600c83 0 150 -67 150 -150c0 -100 -150 -250 -150 -250s-150 150 -150 250c0 83 67 150 150 150zM350 500
|
||||
c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
|
||||
<glyph glyph-name="92" unicode="" horiz-adv-x="600"
|
||||
d="M0 700h200v-600h-200v600zM400 700h200v-600h-200v600z" />
|
||||
<glyph glyph-name="93" unicode="" horiz-adv-x="600"
|
||||
d="M0 700l600 -300l-600 -300v600z" />
|
||||
<glyph glyph-name="94" unicode="" horiz-adv-x="600"
|
||||
d="M300 700c166 0 300 -134 300 -300s-134 -300 -300 -300s-300 134 -300 300s134 300 300 300z" />
|
||||
<glyph glyph-name="95" unicode=""
|
||||
d="M400 700v-600l-400 300zM400 400l400 300v-600z" />
|
||||
<glyph glyph-name="96" unicode=""
|
||||
d="M0 700l400 -300l-400 -300v600zM400 100v600l400 -300z" />
|
||||
<glyph glyph-name="97" unicode=""
|
||||
d="M0 700h200v-600h-200v600zM200 400l500 300v-600z" />
|
||||
<glyph glyph-name="98" unicode=""
|
||||
d="M0 700l500 -300l-500 -300v600zM500 100v600h200v-600h-200z" />
|
||||
<glyph glyph-name="99" unicode="" horiz-adv-x="600"
|
||||
d="M0 700h600v-600h-600v600z" />
|
||||
<glyph glyph-name="9a" unicode=""
|
||||
d="M200 800h400v-200h200v-400h-200v-200h-400v200h-200v400h200v200z" />
|
||||
<glyph glyph-name="9b" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM0 403h800v-100h-800v100zM0 103h800v-100h-800v100z" />
|
||||
<glyph glyph-name="9c" unicode="" horiz-adv-x="600"
|
||||
d="M278 700c7 2 13 4 22 4c55 0 100 -45 100 -100v-4v-200c0 -55 -45 -100 -100 -100s-100 45 -100 100v200v2c0 44 35 88 78 98zM34 500h4h3c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-50c0 -111 89 -200 200 -200s200 89 200 200v50c0 28 22 50 50 50s50 -22 50 -50v-50
|
||||
c0 -148 -109 -270 -250 -294v-106h50c55 0 100 -45 100 -100h-400c0 55 45 100 100 100h50v106c-141 24 -250 146 -250 294v50v2c0 20 15 42 34 48z" />
|
||||
<glyph glyph-name="9d" unicode=""
|
||||
d="M0 500h800v-200h-800v200z" />
|
||||
<glyph glyph-name="9e" unicode=""
|
||||
d="M34 700h4h3h4h5h700c28 0 50 -22 50 -50v-500c0 -28 -22 -50 -50 -50h-250v-100h100c55 0 100 -45 100 -100h-600c0 55 45 100 100 100h100v100h-250c-28 0 -50 22 -50 50v500v2c0 20 15 42 34 48zM100 600v-400h600v400h-600z" />
|
||||
<glyph glyph-name="9f" unicode=""
|
||||
d="M272 700c-14 -40 -22 -83 -22 -128c0 -221 179 -400 400 -400c45 0 88 8 128 22c-53 -158 -202 -272 -378 -272c-221 0 -400 179 -400 400c0 176 114 325 272 378z" />
|
||||
<glyph glyph-name="a0" unicode=""
|
||||
d="M350 700l150 -150h-100v-150h150v100l150 -150l-150 -150v100h-150v-150h100l-150 -150l-150 150h100v150h-150v-100l-150 150l150 150v-100h150v150h-100z" />
|
||||
<glyph glyph-name="a1" unicode=""
|
||||
d="M800 800v-550c0 -83 -67 -150 -150 -150s-150 67 -150 150s67 150 150 150c17 0 35 -4 50 -9v206c-201 -6 -327 -27 -400 -50v-397c0 -83 -67 -150 -150 -150s-150 67 -150 150s67 150 150 150c17 0 35 -4 50 -9v409s100 100 600 100z" />
|
||||
<glyph glyph-name="a2" unicode="" horiz-adv-x="700"
|
||||
d="M499 700c51 0 102 -20 141 -59c78 -78 78 -203 0 -281l-250 -244c-48 -48 -127 -48 -175 0s-48 127 0 175l96 97l69 -69l-90 -94l-7 -3c-10 -10 -10 -28 0 -38s28 -10 38 0l250 247c37 40 39 102 0 141s-104 40 -144 0l-278 -275c-66 -69 -68 -179 0 -247
|
||||
c69 -69 181 -69 250 0l9 12l116 113l69 -69l-125 -125c-107 -107 -281 -107 -388 0s-107 281 0 388l278 272c39 39 90 59 141 59z" />
|
||||
<glyph glyph-name="a3" unicode=""
|
||||
d="M600 800l200 -200l-100 -100l-200 200zM400 600l200 -200l-400 -400h-200v200z" />
|
||||
<glyph glyph-name="a4" unicode=""
|
||||
d="M550 800c83 0 150 -90 150 -200s-67 -200 -150 -200c-22 0 -40 8 -59 19c6 26 9 52 9 81c0 84 -27 158 -72 212c27 52 71 88 122 88zM250 700c83 0 150 -90 150 -200s-67 -200 -150 -200s-150 90 -150 200s67 200 150 200zM725 384c44 -22 75 -66 75 -118v-166h-200v66
|
||||
c0 50 -17 96 -44 134c66 2 126 33 169 84zM75 284c45 -53 106 -84 175 -84s130 31 175 84c44 -22 75 -66 75 -118v-166h-500v166c0 52 31 96 75 118z" />
|
||||
<glyph glyph-name="a5" unicode=""
|
||||
d="M400 800c110 0 200 -112 200 -250s-90 -250 -200 -250s-200 112 -200 250s90 250 200 250zM191 300c54 -61 128 -100 209 -100s155 39 209 100c106 -5 191 -92 191 -200v-100h-800v100c0 108 85 195 191 200z" />
|
||||
<glyph glyph-name="a6" unicode="" horiz-adv-x="600"
|
||||
d="M19 800h462c11 0 19 -8 19 -19v-762c0 -11 -8 -19 -19 -19h-462c-11 0 -19 8 -19 19v762c0 11 8 19 19 19zM100 700v-500h300v500h-300zM250 150c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
|
||||
<glyph glyph-name="a7" unicode=""
|
||||
d="M350 800c17 0 34 -1 50 -3v-397l-297 297c63 64 150 103 247 103zM500 694c169 -25 300 -168 300 -344c0 -193 -157 -350 -350 -350c-85 0 -161 31 -222 81l272 272v341zM91 562l237 -234l-212 -212c-70 55 -116 138 -116 234c0 84 35 158 91 212z" />
|
||||
<glyph glyph-name="a8" unicode=""
|
||||
d="M92 650c0 23 20 50 46 50h3h4h5h400c28 0 50 -22 50 -50s-22 -50 -50 -50h-50v-200h100c55 0 100 -45 100 -100h-300v-300l-56 -100l-44 100v300h-300c0 55 45 100 100 100h100v200h-50c-2 0 -6 -1 -8 -1c-28 0 -50 23 -50 51z" />
|
||||
<glyph glyph-name="a9" unicode=""
|
||||
d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM300 600v-400l300 200z" />
|
||||
<glyph glyph-name="aa" unicode=""
|
||||
d="M300 800h200v-300h300v-200h-300v-300h-200v300h-300v200h300v300z" />
|
||||
<glyph glyph-name="ab" unicode=""
|
||||
d="M300 800h100v-400h-100v400zM172 656l62 -78l-40 -31c-58 -46 -94 -117 -94 -197c0 -139 111 -250 250 -250s250 111 250 250c0 80 -39 151 -97 197l-37 31l62 78l38 -31c82 -64 134 -164 134 -275c0 -193 -157 -350 -350 -350s-350 157 -350 350c0 111 53 211 134 275z
|
||||
" />
|
||||
<glyph glyph-name="ac" unicode=""
|
||||
d="M200 800h400v-200h-400v200zM9 500h782c6 0 9 -3 9 -9v-282c0 -6 -3 -9 -9 -9h-91v200h-600v-200h-91c-6 0 -9 3 -9 9v282c0 6 3 9 9 9zM200 300h400v-300h-400v300z" />
|
||||
<glyph glyph-name="ad" unicode=""
|
||||
d="M0 700h100v-700h-100v700zM700 700h100v-700h-100v700zM200 600h200v-100h-200v100zM300 400h200v-100h-200v100zM400 200h200v-100h-200v100z" />
|
||||
<glyph glyph-name="ae" unicode=""
|
||||
d="M325 700c42 -141 87 -280 131 -419c29 74 59 148 88 222c30 -57 58 -114 87 -172h169v-100h-231l-13 28c-37 -92 -74 -184 -112 -275c-38 129 -79 257 -119 385c-42 -133 -83 -267 -125 -400c-28 88 -56 175 -84 262h-116v100h188l9 -34l3 -6c42 137 83 273 125 409z" />
|
||||
<glyph glyph-name="af" unicode=""
|
||||
d="M200 600c0 57 43 100 100 100s100 -43 100 -100c0 -28 -18 -48 -28 -72c-3 -6 -3 -16 -3 -28h231v-231c12 0 22 0 28 3c24 10 44 28 72 28c57 0 100 -43 100 -100s-43 -100 -100 -100c-28 0 -48 18 -72 28c-6 3 -16 3 -28 3v-231h-231c0 12 0 22 3 28c10 24 28 44 28 72
|
||||
c0 57 -43 100 -100 100s-100 -43 -100 -100c0 -28 18 -48 28 -72c3 -6 3 -16 3 -28h-231v600h231c0 12 0 22 -3 28c-10 24 -28 44 -28 72z" />
|
||||
<glyph glyph-name="b0" unicode="" horiz-adv-x="500"
|
||||
d="M247 700c84 0 148 -20 191 -59s59 -93 59 -141c0 -117 -69 -181 -119 -225s-81 -67 -81 -150v-25h-100v25c0 117 65 181 115 225s85 67 85 150c0 25 -8 48 -28 66s-56 34 -122 34s-97 -18 -116 -37s-27 -43 -31 -69l-100 12c5 38 19 88 59 128s103 66 188 66zM197 0h100
|
||||
v-100h-100v100z" />
|
||||
<glyph glyph-name="b1" unicode=""
|
||||
d="M450 800c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -69 -48 -127 -112 -144c-22 55 -75 94 -138 94c-20 0 -39 -5 -56 -12c-17 64 -75 112 -144 112s-127 -48 -144 -112c-17 7 -36 12 -56 12c-37 0 -71 -12 -97 -34c-33 36 -53 82 -53 134
|
||||
c0 110 90 200 200 200c23 114 129 200 250 200zM334 300h4h3c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-200c0 -28 -22 -50 -50 -50s-50 22 -50 50v200v2c0 20 15 42 34 48zM134 200h4h3c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-100c0 -28 -22 -50 -50 -50s-50 22 -50 50v100v2
|
||||
c0 20 15 42 34 48zM534 200h3h4c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-100c0 -28 -22 -50 -50 -50s-50 22 -50 50v100v2c0 20 15 42 34 48z" />
|
||||
<glyph glyph-name="b2" unicode=""
|
||||
d="M600 800l200 -150l-200 -150v100h-50l-153 -191l175 -206l6 -3h22v100l200 -150l-200 -150v100h-25c-35 0 -56 12 -78 38l-166 190l-153 -190c-22 -27 -43 -38 -78 -38h-100v100h100l166 206l-163 191l-3 3h-100v100h100c34 0 56 -12 78 -38l153 -178l141 178
|
||||
c22 27 43 38 78 38h50v100z" />
|
||||
<glyph glyph-name="b3" unicode=""
|
||||
d="M400 800c110 0 209 -47 281 -119l119 119v-300h-300l109 109c-54 55 -126 91 -209 91c-166 0 -300 -134 -300 -300s134 -300 300 -300c83 0 158 34 212 88l72 -72c-72 -72 -174 -116 -284 -116c-220 0 -400 180 -400 400s180 400 400 400z" />
|
||||
<glyph glyph-name="b4" unicode=""
|
||||
d="M400 800h400v-400l-166 166l-400 -400l166 -166h-400v400l166 -166l400 400z" />
|
||||
<glyph glyph-name="b5" unicode="" horiz-adv-x="600"
|
||||
d="M250 800l250 -300h-200v-200h200l-250 -300l-250 300h200v200h-200z" />
|
||||
<glyph glyph-name="b6" unicode=""
|
||||
d="M300 600v-200h200v200l300 -250l-300 -250v200h-200v-200l-300 250z" />
|
||||
<glyph glyph-name="b7" unicode=""
|
||||
d="M0 800c441 0 800 -359 800 -800h-200c0 333 -267 600 -600 600v200zM0 500c275 0 500 -225 500 -500h-200c0 167 -133 300 -300 300v200zM0 200c110 0 200 -90 200 -200h-200v200z" />
|
||||
<glyph glyph-name="b8" unicode=""
|
||||
d="M100 800c386 0 700 -314 700 -700h-100c0 332 -268 600 -600 600v100zM100 600c276 0 500 -224 500 -500h-100c0 222 -178 400 -400 400v100zM100 400c165 0 300 -135 300 -300h-100c0 111 -89 200 -200 200v100zM100 200c55 0 100 -45 100 -100s-45 -100 -100 -100
|
||||
s-100 45 -100 100s45 100 100 100z" />
|
||||
<glyph glyph-name="b9" unicode=""
|
||||
d="M300 800h400c55 0 100 -45 100 -100v-200h-400v150c0 28 -22 50 -50 50s-50 -22 -50 -50v-250h400v-300c0 -55 -45 -100 -100 -100h-500c-55 0 -100 45 -100 100v200h100v-150c0 -28 22 -50 50 -50s50 22 50 50v550c0 55 45 100 100 100z" />
|
||||
<glyph glyph-name="ba" unicode=""
|
||||
d="M75 700h225v-100h-200v-500h400v100h100v-125c0 -41 -34 -75 -75 -75h-450c-41 0 -75 34 -75 75v550c0 41 34 75 75 75zM600 700l200 -200l-200 -200v100h-200c-94 0 -173 -65 -194 -153c23 199 189 353 394 353v100z" />
|
||||
<glyph glyph-name="bb" unicode=""
|
||||
d="M500 700l300 -284l-300 -316v200h-100c-200 0 -348 -102 -400 -300c0 295 100 500 500 500v200z" />
|
||||
<glyph glyph-name="bc" unicode=""
|
||||
d="M381 791l19 9l19 -9c127 -53 253 -108 381 -160v-31c0 -166 -67 -313 -147 -419c-40 -53 -83 -97 -125 -128s-82 -53 -128 -53s-86 22 -128 53s-85 75 -125 128c-80 107 -147 253 -147 419v31c128 52 254 107 381 160zM400 100v591l-294 -122c8 -126 58 -243 122 -328
|
||||
c35 -46 73 -86 106 -110s62 -31 66 -31z" />
|
||||
<glyph glyph-name="bd" unicode=""
|
||||
d="M600 800h100v-800h-100v800zM400 700h100v-700h-100v700zM200 500h100v-500h-100v500zM0 300h100v-300h-100v300z" />
|
||||
<glyph glyph-name="be" unicode=""
|
||||
d="M300 800h100v-200h200l100 -100l-100 -100h-200v-400h-100v500h-200l-100 100l100 100h200v100z" />
|
||||
<glyph glyph-name="bf" unicode=""
|
||||
d="M200 800h100v-600h200l-250 -200l-250 200h200v600zM400 800h200v-100h-200v100zM400 600h300v-100h-300v100zM400 400h400v-100h-400v100z" />
|
||||
<glyph glyph-name="c0" unicode=""
|
||||
d="M200 800h100v-600h200l-250 -200l-250 200h200v600zM400 800h400v-100h-400v100zM400 600h300v-100h-300v100zM400 400h200v-100h-200v100z" />
|
||||
<glyph glyph-name="c1" unicode=""
|
||||
d="M75 700h650c41 0 75 -34 75 -75v-550c0 -41 -34 -75 -75 -75h-650c-41 0 -75 34 -75 75v550c0 41 34 75 75 75zM100 600v-100h100v100h-100zM300 600v-100h400v100h-400zM100 400v-100h100v100h-100zM300 400v-100h400v100h-400zM100 200v-100h100v100h-100zM300 200
|
||||
v-100h400v100h-400z" />
|
||||
<glyph glyph-name="c2" unicode=""
|
||||
d="M400 800l100 -300h300l-250 -200l100 -300l-250 200l-250 -200l100 300l-250 200h300z" />
|
||||
<glyph glyph-name="c3" unicode=""
|
||||
d="M400 800c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM150 700c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM650 700c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM400 600c110 0 200 -90 200 -200
|
||||
s-90 -200 -200 -200s-200 90 -200 200s90 200 200 200zM50 450c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM750 450c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM150 200c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50
|
||||
s22 50 50 50zM650 200c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM400 100c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50z" />
|
||||
<glyph glyph-name="c4" unicode=""
|
||||
d="M34 800h632c18 0 34 -16 34 -34v-732c0 -18 -16 -34 -34 -34h-632c-18 0 -34 16 -34 34v732c0 18 16 34 34 34zM100 700v-500h500v500h-500zM350 150c-38 0 -63 -42 -44 -75s69 -33 88 0s-6 75 -44 75z" />
|
||||
<glyph glyph-name="c5" unicode=""
|
||||
d="M0 800h300l500 -500l-300 -300l-500 500v300zM200 700c-55 0 -100 -45 -100 -100s45 -100 100 -100s100 45 100 100s-45 100 -100 100z" />
|
||||
<glyph glyph-name="c6" unicode=""
|
||||
d="M0 600h200l300 -300l-200 -200l-300 300v200zM340 600h160l300 -300l-200 -200l-78 78l119 122zM150 500c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
|
||||
<glyph glyph-name="c7" unicode=""
|
||||
d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 -300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM400 600c110 0 200 -90 200 -200s-90 -200 -200 -200s-200 90 -200 200
|
||||
s90 200 200 200zM400 500c-56 0 -100 -44 -100 -100s44 -100 100 -100s100 44 100 100s-44 100 -100 100z" />
|
||||
<glyph glyph-name="c8" unicode=""
|
||||
d="M0 700h559l-100 -100h-359v-500h500v159l100 100v-359h-700v700zM700 700l100 -100l-400 -400l-200 200l100 100l100 -100z" />
|
||||
<glyph glyph-name="c9" unicode=""
|
||||
d="M9 800h782c6 0 9 -3 9 -9v-782c0 -6 -3 -9 -9 -9h-782c-6 0 -9 3 -9 9v782c0 6 3 9 9 9zM150 722l-72 -72l100 -100l-100 -100l72 -72l172 172zM400 500v-100h300v100h-300z" />
|
||||
<glyph glyph-name="ca" unicode=""
|
||||
d="M0 800h800v-200h-50c0 55 -45 100 -100 100h-150v-550c0 -28 22 -50 50 -50h50v-100h-400v100h50c28 0 50 22 50 50v550h-150c-55 0 -100 -45 -100 -100h-50v200z" />
|
||||
<glyph glyph-name="cb" unicode=""
|
||||
d="M0 700h100v-400h-100v400zM200 700h350c21 0 39 -13 47 -31c0 0 103 -291 103 -319s-22 -50 -50 -50h-150c-28 0 -50 -25 -50 -50s39 -158 47 -184s-5 -55 -31 -63s-52 5 -66 31s-109 219 -128 238s-44 28 -72 28v400z" />
|
||||
<glyph glyph-name="cc" unicode=""
|
||||
d="M400 666c10 19 28 32 47 34l19 -3c26 -8 39 -37 31 -63s-47 -159 -47 -184s22 -50 50 -50h150c28 0 50 -22 50 -50s-103 -319 -103 -319c-8 -18 -26 -31 -47 -31h-350v400c28 0 53 9 72 28s114 212 128 238zM0 400h100v-400h-100v400z" />
|
||||
<glyph glyph-name="cd" unicode=""
|
||||
d="M200 700h300v-100h-100v-6c25 -4 50 -8 72 -16l-34 -94c-28 11 -58 16 -88 16c-139 0 -250 -111 -250 -250s111 -250 250 -250s250 111 250 250c0 31 -5 60 -16 88l91 37c14 -38 25 -81 25 -125c0 -193 -157 -350 -350 -350s-350 157 -350 350c0 176 130 323 300 347v3
|
||||
h-100v100zM700 584c0 0 -296 -348 -316 -368s-48 -20 -68 0s-20 48 0 68s384 300 384 300z" />
|
||||
<glyph glyph-name="ce" unicode=""
|
||||
d="M600 700l200 -150l-200 -150v100h-600v100h600v100zM200 300v-100h600v-100h-600v-100l-200 150z" />
|
||||
<glyph glyph-name="cf" unicode=""
|
||||
d="M300 800h100c55 0 100 -45 100 -100h100c55 0 100 -45 100 -100h-700c0 55 45 100 100 100h100c0 55 45 100 100 100zM100 500h100v-350c0 -28 22 -50 50 -50s50 22 50 50v350h100v-350c0 -28 22 -50 50 -50s50 22 50 50v350h100v-481c0 -11 -8 -19 -19 -19h-462
|
||||
c-11 0 -19 8 -19 19v481z" />
|
||||
<glyph glyph-name="d0" unicode=""
|
||||
d="M100 800h200v-400c0 -55 45 -100 100 -100s100 45 100 100v400h100v-400c0 -110 -90 -200 -200 -200h-50c-138 0 -250 90 -250 200v400zM0 100h700v-100h-700v100z" />
|
||||
<glyph glyph-name="d1" unicode=""
|
||||
d="M9 700h182c6 0 9 -3 9 -9v-482c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v482c0 6 3 9 9 9zM609 700h182c6 0 9 -3 9 -9v-482c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v482c0 6 3 9 9 9zM309 500h182c6 0 9 -3 9 -9v-282c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v282
|
||||
c0 6 3 9 9 9zM0 100h800v-100h-800v100z" />
|
||||
<glyph glyph-name="d2" unicode=""
|
||||
d="M10 700h181c6 0 9 -3 9 -9v-191h-200v191c0 6 4 9 10 9zM610 700h181c6 0 9 -3 9 -9v-191h-200v191c0 6 5 9 10 9zM310 600h181c6 0 9 -3 9 -9v-91h-200v91c0 6 4 9 10 9zM0 400h800v-100h-800v100zM0 200h200v-191c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v191zM300 200
|
||||
h200v-91c0 -6 -3 -9 -9 -9h-181c-6 0 -10 3 -10 9v91zM600 200h200v-191c0 -6 -3 -9 -9 -9h-181c-6 0 -10 3 -10 9v191z" />
|
||||
<glyph glyph-name="d3" unicode=""
|
||||
d="M0 700h800v-100h-800v100zM9 500h182c6 0 9 -3 9 -9v-482c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v482c0 6 3 9 9 9zM309 500h182c6 0 9 -3 9 -9v-282c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v282c0 6 3 9 9 9zM609 500h182c6 0 9 -3 9 -9v-482c0 -6 -3 -9 -9 -9h-182
|
||||
c-6 0 -9 3 -9 9v482c0 6 3 9 9 9z" />
|
||||
<glyph glyph-name="d4" unicode=""
|
||||
d="M50 600h500c28 0 50 -22 50 -50v-150l100 100h100v-300h-100l-100 100v-150c0 -28 -22 -50 -50 -50h-500c-28 0 -50 22 -50 50v400c0 28 22 50 50 50z" />
|
||||
<glyph glyph-name="d5" unicode=""
|
||||
d="M334 800h66v-800h-66l-134 200h-200v400h200zM500 600v100c26 0 52 -4 75 -10c130 -33 225 -150 225 -290s-95 -258 -225 -291h-3c-23 -6 -47 -9 -72 -9v100c17 0 34 2 50 6c86 22 150 100 150 194s-64 172 -150 194c-16 4 -33 6 -50 6zM500 500l25 -3
|
||||
c44 -11 75 -51 75 -97s-32 -86 -75 -97l-25 -3v200z" />
|
||||
<glyph glyph-name="d6" unicode="" horiz-adv-x="600"
|
||||
d="M334 800h66v-800h-66l-134 200h-200v400h200zM500 500l25 -3c44 -11 75 -51 75 -97s-32 -86 -75 -97l-25 -3v200z" />
|
||||
<glyph glyph-name="d7" unicode="" horiz-adv-x="400"
|
||||
d="M334 800h66v-800h-66l-134 200h-200v400h200z" />
|
||||
<glyph glyph-name="d8" unicode=""
|
||||
d="M309 800h82c6 0 10 -4 12 -9l294 -682l3 -19v-81c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v81l3 19l294 682c2 5 6 9 12 9zM300 500v-200h100v200h-100zM300 200v-100h100v100h-100z" />
|
||||
<glyph glyph-name="d9" unicode=""
|
||||
d="M375 800c138 0 269 -39 378 -109l-53 -82c-93 60 -205 91 -325 91c-119 0 -229 -32 -322 -91l-53 82c109 70 237 109 375 109zM375 500c78 0 154 -23 216 -62l-53 -85c-46 30 -104 47 -163 47c-60 0 -112 -17 -159 -47l-54 85c62 40 134 62 213 62zM375 200
|
||||
c55 0 100 -45 100 -100s-45 -100 -100 -100s-100 45 -100 100s45 100 100 100z" />
|
||||
<glyph glyph-name="da" unicode="" horiz-adv-x="900"
|
||||
d="M551 800c16 0 32 0 47 -3l-97 -97v-200h200l97 97c3 -15 3 -31 3 -47c0 -138 -112 -250 -250 -250c-32 0 -62 8 -90 19l-288 -291c-20 -20 -46 -28 -72 -28s-52 8 -72 28c-39 39 -39 105 0 144l291 287c-11 28 -19 59 -19 91c0 138 112 250 250 250zM101 150
|
||||
c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
|
||||
<glyph glyph-name="db" unicode=""
|
||||
d="M141 700c84 -84 169 -167 253 -250c82 83 167 165 247 250l143 -141l-253 -253c84 -82 167 -166 253 -247l-143 -143c-81 86 -165 169 -247 253l-253 -253l-141 143c85 80 167 164 250 247c-83 84 -166 169 -250 253z" />
|
||||
<glyph glyph-name="dc" unicode=""
|
||||
d="M0 800h100l231 -300h38l231 300h100l-225 -300h225v-100h-300v-100h300v-100h-300v-200h-100v200h-300v100h300v100h-300v100h225z" />
|
||||
<glyph glyph-name="dd" unicode="" horiz-adv-x="900"
|
||||
d="M350 800c193 0 350 -157 350 -350c0 -61 -17 -119 -44 -169c4 -2 10 -6 13 -9l103 -100c16 -16 30 -49 30 -72c0 -56 -46 -102 -102 -102c-23 0 -56 14 -72 30l-100 103c-3 3 -7 9 -9 13c-50 -28 -108 -44 -169 -44c-193 0 -350 157 -350 350s157 350 350 350zM350 700
|
||||
c-139 0 -250 -111 -250 -250s111 -250 250 -250c62 0 119 23 163 60c7 11 19 25 31 31l3 3c34 43 53 97 53 156c0 139 -111 250 -250 250zM300 600h100v-100h100v-100h-100v-100h-100v100h-100v100h100v100z" />
|
||||
<glyph glyph-name="de" unicode="" horiz-adv-x="900"
|
||||
d="M350 800c193 0 350 -157 350 -350c0 -61 -17 -119 -44 -169c4 -2 10 -6 13 -9l103 -100c16 -16 30 -49 30 -72c0 -56 -46 -102 -102 -102c-23 0 -56 14 -72 30l-100 103c-3 3 -7 9 -9 13c-50 -28 -108 -44 -169 -44c-193 0 -350 157 -350 350s157 350 350 350zM350 700
|
||||
c-139 0 -250 -111 -250 -250s111 -250 250 -250c62 0 119 23 163 60c7 11 19 25 31 31l3 3c34 43 53 97 53 156c0 139 -111 250 -250 250zM200 500h300v-100h-300v100z" />
|
||||
</font>
|
||||
</defs></svg>
|
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,183 @@
|
|||
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
|
||||
|
||||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
a, .btn-link {
|
||||
color: #0366d6;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
#app {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.main .top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.main .top-row > a, .main .top-row .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
.main .top-row a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.sidebar .top-row {
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.sidebar .navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.sidebar .oi {
|
||||
width: 2rem;
|
||||
font-size: 1.1rem;
|
||||
vertical-align: text-top;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.sidebar .nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar .nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.sidebar .nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.sidebar .nav-item a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.sidebar .nav-item a.active {
|
||||
background-color: rgba(255,255,255,0.25);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar .nav-item a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 1.1rem;
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.valid.modified:not([type=checkbox]) {
|
||||
outline: 1px solid #26b050;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
outline: 1px solid red;
|
||||
}
|
||||
|
||||
.validation-message {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#blazor-error-ui {
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
||||
display: none;
|
||||
left: 0;
|
||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#blazor-error-ui .dismiss {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.main .top-row:not(.auth) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main .top-row.auth {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.main .top-row a, .main .top-row .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#app {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.main .top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.main > div {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar .collapse {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>gRPC-Web in Blazor</title>
|
||||
<base href="/" />
|
||||
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="css/site.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">Loading...</div>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
An unhandled error has occurred.
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package count;
|
||||
|
||||
service Counter {
|
||||
rpc StartCounter (CounterRequest) returns (stream CounterResponse);
|
||||
}
|
||||
|
||||
message CounterRequest {
|
||||
int32 start = 1;
|
||||
}
|
||||
|
||||
message CounterResponse {
|
||||
int32 count = 1;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
package weather;
|
||||
|
||||
service WeatherForecasts {
|
||||
rpc GetWeatherForecasts (google.protobuf.Empty) returns (GetWeatherForecastsResponse);
|
||||
}
|
||||
|
||||
message GetWeatherForecastsResponse {
|
||||
repeated WeatherForecast forecasts = 1;
|
||||
}
|
||||
|
||||
message WeatherForecast {
|
||||
google.protobuf.Timestamp date = 1;
|
||||
int32 temperatureC = 2;
|
||||
string summary = 3;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using Microsoft.AspNetCore.ResponseCompression;
|
||||
using Server.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddGrpc();
|
||||
builder.Services.AddResponseCompression(opts =>
|
||||
{
|
||||
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
|
||||
new[] { "application/octet-stream" });
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
app.UseResponseCompression();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseWebAssemblyDebugging();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseBlazorFrameworkFiles();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseGrpcWeb();
|
||||
|
||||
app.MapGrpcService<WeatherService>().EnableGrpcWeb();
|
||||
app.MapGrpcService<CounterService>().EnableGrpcWeb();
|
||||
app.MapFallbackToFile("index.html");
|
||||
|
||||
app.Run();
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:59193/",
|
||||
"sslPort": 44375
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Server": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<UserSecretsId>46982f83-f153-443e-b589-4b2bc7b5945e</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\weather.proto" GrpcServices="Server" Link="Protos\weather.proto" />
|
||||
<Protobuf Include="..\Proto\count.proto" GrpcServices="Server" Link="Protos\count.proto" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
|
||||
<PackageReference Include="Grpc.AspNetCore" />
|
||||
<PackageReference Include="Grpc.AspNetCore.Web" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Client\Client.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -16,31 +16,28 @@
|
|||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Count;
|
||||
using Grpc.Core;
|
||||
|
||||
namespace BenchmarkClient.ChannelFactory
|
||||
namespace Server.Services
|
||||
{
|
||||
public class GrpcCoreChannelFactory : IChannelFactory
|
||||
public class CounterService : Counter.CounterBase
|
||||
{
|
||||
private readonly string _target;
|
||||
|
||||
public GrpcCoreChannelFactory(string target)
|
||||
public override async Task StartCounter(CounterRequest request, IServerStreamWriter<CounterResponse> responseStream, ServerCallContext context)
|
||||
{
|
||||
_target = target;
|
||||
}
|
||||
var count = request.Start;
|
||||
|
||||
public async Task<ChannelBase> CreateAsync()
|
||||
{
|
||||
var channel = new Channel(_target, ChannelCredentials.Insecure);
|
||||
await channel.ConnectAsync();
|
||||
while (!context.CancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await responseStream.WriteAsync(new CounterResponse
|
||||
{
|
||||
Count = ++count
|
||||
});
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
public Task DisposeAsync(ChannelBase channel)
|
||||
{
|
||||
return ((Channel)channel).ShutdownAsync();
|
||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Grpc.Core;
|
||||
using Weather;
|
||||
|
||||
namespace Server.Services
|
||||
{
|
||||
public class WeatherService : WeatherForecasts.WeatherForecastsBase
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
public override Task<GetWeatherForecastsResponse> GetWeatherForecasts(Empty request, ServerCallContext context)
|
||||
{
|
||||
var rng = new Random();
|
||||
var results = Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateTime.UtcNow.AddDays(index).ToTimestamp(),
|
||||
TemperatureC = rng.Next(-20, 55),
|
||||
Summary = Summaries[rng.Next(Summaries.Length)]
|
||||
}).ToArray();
|
||||
|
||||
var response = new GetWeatherForecastsResponse();
|
||||
response.Forecasts.AddRange(results);
|
||||
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<Solution>
|
||||
<Project Path="Server/Server.csproj" />
|
||||
</Solution>
|
|
@ -0,0 +1,39 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using Server.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddGrpc();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseGrpcWeb();
|
||||
|
||||
app.MapGrpcService<GreeterService>().EnableGrpcWeb();
|
||||
|
||||
app.Run();
|
|
@ -0,0 +1,44 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<SpaRoot>wwwroot\</SpaRoot>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**;$(SpaRoot)dist\**</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\greet.proto" GrpcServices="Server" Link="Protos\greet.proto" />
|
||||
|
||||
<PackageReference Include="Grpc.AspNetCore" />
|
||||
<PackageReference Include="Grpc.AspNetCore.Web" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
|
||||
<!-- Ensure Node.js is installed -->
|
||||
<Exec Command="node --version" ContinueOnError="true">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
|
||||
</Exec>
|
||||
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
|
||||
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
|
||||
<!-- Include source map for debugging (for other source map options see https://webpack.js.org/configuration/devtool/ ) -->
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npx webpack --debug --devtool inline-source-map scripts/index.js" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
|
||||
<Exec WorkingDirectory="$(SpaRoot)" Command="npx webpack scripts/index.js" />
|
||||
|
||||
<!-- Include the newly-built files in the publish output -->
|
||||
<ItemGroup>
|
||||
<DistFiles Include="$(SpaRoot)dist\**" />
|
||||
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
|
||||
<RelativePath>%(DistFiles.Identity)</RelativePath>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</ResolvedFileToPublish>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,44 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Greet;
|
||||
using Grpc.Core;
|
||||
|
||||
namespace Server.Services
|
||||
{
|
||||
public class GreeterService : Greeter.GreeterBase
|
||||
{
|
||||
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
|
||||
{
|
||||
return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}" });
|
||||
}
|
||||
|
||||
public override async Task SayHellos(HelloRequest request, IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
|
||||
{
|
||||
var i = 0;
|
||||
while (!context.CancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await responseStream.WriteAsync(new HelloReply { Message = $"Hello {request.Name} {i}" });
|
||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Grpc": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/dist-server
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
|
@ -0,0 +1,12 @@
|
|||
# gRPC-Web generated client
|
||||
|
||||
gRPC-Web JavaScript clients and messages are generated using `protoc` the gRPC-Web code generator plugin. Instructions for using it are available [here](https://github.com/grpc/grpc-web#code-generator-plugin).
|
||||
|
||||
Files in this directory are generated from *greet.proto*:
|
||||
|
||||
* *greet_grpc_web_pb.js* contains the gRPC-Web client.
|
||||
* *greet_pb.js* contains gRPC messages.
|
||||
|
||||
Example of using `protoc` from PowerShell (`protoc` and `protoc-gen-grpc-web` should be on your computer and discoverable from your PATH):
|
||||
|
||||
> protoc greet.proto --js_out=import_style=commonjs:CHANGE_TO_SCRIPTS_DIRECTORY --grpc-web_out=import_style=commonjs,mode=grpcwebtext:CHANGE_TO_SCRIPTS_DIRECTORY --plugin=protoc-gen-grpc-web=CHANGE_TO_PROTOC_GEN_GRPC_WEB_EXE_PATH
|
|
@ -0,0 +1,225 @@
|
|||
/**
|
||||
* @fileoverview gRPC-Web generated client stub for greet
|
||||
* @enhanceable
|
||||
* @public
|
||||
*/
|
||||
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
|
||||
|
||||
|
||||
const grpc = {};
|
||||
grpc.web = require('grpc-web');
|
||||
|
||||
const proto = {};
|
||||
proto.greet = require('./greet_pb.js');
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.greet.GreeterClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.greet.GreeterPromiseClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.greet.HelloRequest,
|
||||
* !proto.greet.HelloReply>}
|
||||
*/
|
||||
const methodDescriptor_Greeter_SayHello = new grpc.web.MethodDescriptor(
|
||||
'/greet.Greeter/SayHello',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.greet.HelloRequest,
|
||||
proto.greet.HelloReply,
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.greet.HelloReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.greet.HelloRequest,
|
||||
* !proto.greet.HelloReply>}
|
||||
*/
|
||||
const methodInfo_Greeter_SayHello = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.greet.HelloReply,
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.greet.HelloReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.greet.HelloReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.greet.HelloReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.greet.GreeterClient.prototype.sayHello =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/greet.Greeter/SayHello',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Greeter_SayHello,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.greet.HelloReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.greet.GreeterPromiseClient.prototype.sayHello =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/greet.Greeter/SayHello',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Greeter_SayHello);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.greet.HelloRequest,
|
||||
* !proto.greet.HelloReply>}
|
||||
*/
|
||||
const methodDescriptor_Greeter_SayHellos = new grpc.web.MethodDescriptor(
|
||||
'/greet.Greeter/SayHellos',
|
||||
grpc.web.MethodType.SERVER_STREAMING,
|
||||
proto.greet.HelloRequest,
|
||||
proto.greet.HelloReply,
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.greet.HelloReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.greet.HelloRequest,
|
||||
* !proto.greet.HelloReply>}
|
||||
*/
|
||||
const methodInfo_Greeter_SayHellos = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.greet.HelloReply,
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.greet.HelloReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request The request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.greet.HelloReply>}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.greet.GreeterClient.prototype.sayHellos =
|
||||
function(request, metadata) {
|
||||
return this.client_.serverStreaming(this.hostname_ +
|
||||
'/greet.Greeter/SayHellos',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Greeter_SayHellos);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.greet.HelloRequest} request The request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.greet.HelloReply>}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.greet.GreeterPromiseClient.prototype.sayHellos =
|
||||
function(request, metadata) {
|
||||
return this.client_.serverStreaming(this.hostname_ +
|
||||
'/greet.Greeter/SayHellos',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Greeter_SayHellos);
|
||||
};
|
||||
|
||||
|
||||
module.exports = proto.greet;
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
// source: greet.proto
|
||||
/**
|
||||
* @fileoverview
|
||||
* @enhanceable
|
||||
* @suppress {messageConventions} JS Compiler reports an error if a variable or
|
||||
* field starts with 'MSG_' and isn't a translatable message.
|
||||
* @public
|
||||
*/
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
|
||||
var jspb = require('google-protobuf');
|
||||
var goog = jspb;
|
||||
var global = Function('return this')();
|
||||
|
||||
goog.exportSymbol('proto.greet.HelloReply', null, global);
|
||||
goog.exportSymbol('proto.greet.HelloRequest', null, global);
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.greet.HelloRequest = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.greet.HelloRequest, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.greet.HelloRequest.displayName = 'proto.greet.HelloRequest';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.greet.HelloReply = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.greet.HelloReply, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.greet.HelloReply.displayName = 'proto.greet.HelloReply';
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.greet.HelloRequest.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.greet.HelloRequest.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.greet.HelloRequest} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.greet.HelloRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
name: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.greet.HelloRequest}
|
||||
*/
|
||||
proto.greet.HelloRequest.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.greet.HelloRequest;
|
||||
return proto.greet.HelloRequest.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.greet.HelloRequest} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.greet.HelloRequest}
|
||||
*/
|
||||
proto.greet.HelloRequest.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setName(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.greet.HelloRequest.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.greet.HelloRequest.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.greet.HelloRequest} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.greet.HelloRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getName();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string name = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.greet.HelloRequest.prototype.getName = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.greet.HelloRequest} returns this
|
||||
*/
|
||||
proto.greet.HelloRequest.prototype.setName = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.greet.HelloReply.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.greet.HelloReply.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.greet.HelloReply} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.greet.HelloReply.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
message: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.greet.HelloReply}
|
||||
*/
|
||||
proto.greet.HelloReply.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.greet.HelloReply;
|
||||
return proto.greet.HelloReply.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.greet.HelloReply} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.greet.HelloReply}
|
||||
*/
|
||||
proto.greet.HelloReply.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setMessage(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.greet.HelloReply.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.greet.HelloReply.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.greet.HelloReply} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.greet.HelloReply.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getMessage();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string message = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.greet.HelloReply.prototype.getMessage = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.greet.HelloReply} returns this
|
||||
*/
|
||||
proto.greet.HelloReply.prototype.setMessage = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
goog.object.extend(exports, proto.greet);
|
|
@ -0,0 +1,58 @@
|
|||
const { HelloRequest, HelloReply } = require('./greet_pb.js');
|
||||
const { GreeterClient } = require('./greet_grpc_web_pb.js');
|
||||
|
||||
var client = new GreeterClient(window.location.origin);
|
||||
|
||||
var nameInput = document.getElementById('name');
|
||||
var sendInput = document.getElementById('send');
|
||||
var streamInput = document.getElementById('stream');
|
||||
var resultText = document.getElementById('result');
|
||||
var streamingCall = null;
|
||||
|
||||
// Unary call
|
||||
sendInput.onclick = function () {
|
||||
var request = new HelloRequest();
|
||||
request.setName(nameInput.value);
|
||||
|
||||
client.sayHello(request, {}, (err, response) => {
|
||||
resultText.innerHTML = htmlEscape(response.getMessage());
|
||||
});
|
||||
};
|
||||
|
||||
// Server streaming call
|
||||
streamInput.onclick = function () {
|
||||
if (!streamingCall) {
|
||||
sendInput.disabled = true;
|
||||
streamInput.value = 'Stop server stream';
|
||||
resultText.innerHTML = '';
|
||||
|
||||
var request = new HelloRequest();
|
||||
request.setName(nameInput.value);
|
||||
|
||||
streamingCall = client.sayHellos(request, {});
|
||||
streamingCall.on('data', (response) => {
|
||||
resultText.innerHTML += htmlEscape(response.getMessage()) + '<br />';
|
||||
});
|
||||
streamingCall.on('status', (status) => {
|
||||
if (status.code == 0) {
|
||||
resultText.innerHTML += 'Done';
|
||||
} else {
|
||||
resultText.innerHTML += 'Error: ' + htmlEscape(status.details);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
streamingCall.cancel();
|
||||
streamingCall = null;
|
||||
sendInput.disabled = false;
|
||||
streamInput.value = 'Start server stream';
|
||||
}
|
||||
};
|
||||
|
||||
function htmlEscape(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>gRPC-Web ASP.NET Core example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>gRPC-Web ASP.NET Core example</h2>
|
||||
<div>
|
||||
<span>Hello:</span>
|
||||
<input id="name" type="text" />
|
||||
<input id="send" type="button" value="Send unary" />
|
||||
<input id="stream" type="button" value="Start server stream" />
|
||||
</div>
|
||||
<div>
|
||||
<p id="result"></p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="./dist/main.js"></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"version": "1.0.0",
|
||||
"name": "browser-server",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@grpc/proto-loader": "^0.3.0",
|
||||
"google-protobuf": "^3.6.1",
|
||||
"grpc-web": "^1.0.0",
|
||||
"webpack": "^5.94.0",
|
||||
"webpack-cli": "^5.0.1"
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29230.61
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{534AC5F8-2DF2-40BD-87A5-B3D8310118C4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{48A1D3BC-A14B-436A-8822-6DE2BEF8B747}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D22B3129-3BFB-41FA-9FCE-E45EBEF8C2DD}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,4 @@
|
|||
<Solution>
|
||||
<Project Path="Client/Client.csproj" />
|
||||
<Project Path="Server/Server.csproj" />
|
||||
</Solution>
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\certify.proto" GrpcServices="Client" Link="Protos\certify.proto" />
|
||||
|
||||
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
|
||||
<PackageReference Include="Grpc.Net.Client" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageReference Include="Grpc.Tools" Version="$(GrpcPackageVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Google.Protobuf" />
|
||||
<PackageReference Include="Grpc.Net.Client" />
|
||||
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
|
||||
|
||||
<None Update="Certs\client.pfx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
|
|
@ -16,79 +16,66 @@
|
|||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
using Certify;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
|
||||
namespace Client
|
||||
// The server will return 403 (Forbidden). The method requires a certificate
|
||||
await CallCertificateInfo(includeClientCertificate: false);
|
||||
|
||||
// The server will return a successful gRPC response
|
||||
await CallCertificateInfo(includeClientCertificate: true);
|
||||
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
|
||||
static async Task CallCertificateInfo(bool includeClientCertificate)
|
||||
{
|
||||
public class Program
|
||||
try
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
Console.WriteLine($"Setting up HttpClient. Client has certificate: {includeClientCertificate}");
|
||||
using var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
|
||||
{
|
||||
// The server will return 403 (Forbidden). The method requires a certificate
|
||||
await CallCertificateInfo(includeClientCertificate: false);
|
||||
HttpHandler = CreateHttpHandler(includeClientCertificate)
|
||||
});
|
||||
var client = new Certifier.CertifierClient(channel);
|
||||
|
||||
// The server will return a successful gRPC response
|
||||
await CallCertificateInfo(includeClientCertificate: true);
|
||||
Console.WriteLine("Sending gRPC call...");
|
||||
var certificateInfo = await client.GetCertificateInfoAsync(new Empty());
|
||||
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
private static async Task CallCertificateInfo(bool includeClientCertificate)
|
||||
Console.WriteLine($"Server received client certificate: {certificateInfo.HasCertificate}");
|
||||
if (certificateInfo.HasCertificate)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Setting up HttpClient. Client has certificate: {includeClientCertificate}");
|
||||
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
|
||||
{
|
||||
HttpClient = CreateHttpClient(includeClientCertificate)
|
||||
});
|
||||
var client = new Certifier.CertifierClient(channel);
|
||||
|
||||
Console.WriteLine("Sending gRPC call...");
|
||||
var certificateInfo = await client.GetCertificateInfoAsync(new Empty());
|
||||
|
||||
Console.WriteLine($"Server received client certificate: {certificateInfo.HasCertificate}");
|
||||
if (certificateInfo.HasCertificate)
|
||||
{
|
||||
Console.WriteLine($"Client certificate name: {certificateInfo.Name}");
|
||||
}
|
||||
}
|
||||
catch (RpcException ex)
|
||||
{
|
||||
Console.WriteLine($"gRPC error from calling service: {ex.Status.Detail}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine($"Unexpected error calling service.");
|
||||
throw;
|
||||
}
|
||||
Console.WriteLine($"Client certificate name: {certificateInfo.Name}");
|
||||
}
|
||||
|
||||
private static HttpClient CreateHttpClient(bool includeClientCertificate)
|
||||
{
|
||||
var handler = new HttpClientHandler();
|
||||
|
||||
if (includeClientCertificate)
|
||||
{
|
||||
// Load client certificate
|
||||
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
|
||||
var certPath = Path.Combine(basePath!, "Certs", "client.pfx");
|
||||
var clientCertificate = new X509Certificate2(certPath, "1111");
|
||||
handler.ClientCertificates.Add(clientCertificate);
|
||||
}
|
||||
|
||||
// Create client
|
||||
return new HttpClient(handler);
|
||||
}
|
||||
|
||||
}
|
||||
catch (RpcException ex)
|
||||
{
|
||||
Console.WriteLine($"gRPC error from calling service: {ex.Status.Detail}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine($"Unexpected error calling service.");
|
||||
throw;
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static HttpClientHandler CreateHttpHandler(bool includeClientCertificate)
|
||||
{
|
||||
var handler = new HttpClientHandler();
|
||||
|
||||
if (includeClientCertificate)
|
||||
{
|
||||
// Load client certificate
|
||||
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
|
||||
var certPath = Path.Combine(basePath!, "Certs", "client.pfx");
|
||||
var clientCertificate = X509CertificateLoader.LoadPkcs12FromFile(certPath, "1111");
|
||||
handler.ClientCertificates.Add(clientCertificate);
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
|
|
@ -16,31 +16,36 @@
|
|||
|
||||
#endregion
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Microsoft.AspNetCore.Authentication.Certificate;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Https;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Server;
|
||||
|
||||
namespace Server
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.WebHost.ConfigureKestrel(kestrelOptions =>
|
||||
{
|
||||
public class Program
|
||||
kestrelOptions.ConfigureHttpsDefaults(httpsOptions =>
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
httpsOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
|
||||
});
|
||||
});
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.ConfigureKestrel(kestrelOptions =>
|
||||
{
|
||||
kestrelOptions.ConfigureHttpsDefaults(httpsOptions =>
|
||||
{
|
||||
httpsOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
|
||||
});
|
||||
});
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
||||
builder.Services.AddGrpc();
|
||||
builder.Services.AddAuthorization();
|
||||
builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCertificate(options =>
|
||||
{
|
||||
// Not recommended in production environments. The example is using a self-signed test certificate.
|
||||
options.RevocationMode = X509RevocationMode.NoCheck;
|
||||
options.ChainTrustValidationMode = X509ChainTrustMode.CustomRootTrust;
|
||||
options.AllowedCertificateTypes = CertificateTypes.All;
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapGrpcService<CertifierService>();
|
||||
|
||||
app.Run();
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\certify.proto" GrpcServices="Server" Link="Protos\certify.proto" />
|
||||
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="$(GrpcDotNetPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Certificate" Version="$(MicrosoftAspNetCorePackageVersion)" />
|
||||
<PackageReference Include="Grpc.AspNetCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Certificate" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Microsoft.AspNetCore.Authentication.Certificate;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddGrpc();
|
||||
|
||||
services.AddAuthorization();
|
||||
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCertificate(options =>
|
||||
{
|
||||
// Not recommended in production environments. The example is using a self-signed test certificate.
|
||||
options.RevocationMode = X509RevocationMode.NoCheck;
|
||||
options.AllowedCertificateTypes = CertificateTypes.All;
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapGrpcService<CertifierService>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<Solution>
|
||||
<Project Path="Client/Client.csproj" />
|
||||
<Project Path="Server/Server.csproj" />
|
||||
</Solution>
|
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\data_channel.proto" GrpcServices="Client" Link="Protos\data_channel.proto" />
|
||||
|
||||
<PackageReference Include="Google.Protobuf" />
|
||||
<PackageReference Include="Grpc.Net.Client" />
|
||||
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,66 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Text;
|
||||
using DataChannel;
|
||||
using Google.Protobuf;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
|
||||
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
|
||||
var client = new DataChanneler.DataChannelerClient(channel);
|
||||
|
||||
await UploadDataAsync(client);
|
||||
|
||||
await DownloadResultsAsync(client);
|
||||
|
||||
Console.WriteLine("Shutting down");
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
|
||||
static async Task UploadDataAsync(DataChanneler.DataChannelerClient client)
|
||||
{
|
||||
var call = client.UploadData();
|
||||
|
||||
var dataChunks = TestData.Chunk(5);
|
||||
foreach (var chunk in dataChunks)
|
||||
{
|
||||
Console.WriteLine($"Uploading chunk: {chunk.Length} bytes");
|
||||
await call.RequestStream.WriteAsync(new DataRequest { Value = ByteString.CopyFrom(chunk) });
|
||||
}
|
||||
|
||||
await call.RequestStream.CompleteAsync();
|
||||
|
||||
var result = await call;
|
||||
Console.WriteLine($"Total upload processed: {result.BytesProcessed} bytes");
|
||||
}
|
||||
|
||||
static async Task DownloadResultsAsync(DataChanneler.DataChannelerClient client)
|
||||
{
|
||||
var call = client.DownloadResults(new DataRequest { Value = ByteString.CopyFrom(TestData) });
|
||||
|
||||
await foreach (var result in call.ResponseStream.ReadAllAsync())
|
||||
{
|
||||
Console.WriteLine($"Downloaded bytes processed result: {result.BytesProcessed}");
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Program
|
||||
{
|
||||
private static readonly byte[] TestData = Encoding.UTF8.GetBytes("The quick brown fox jumped over the lazy dog.");
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package data_channel;
|
||||
|
||||
service DataChanneler {
|
||||
rpc UploadData (stream DataRequest) returns (DataResult);
|
||||
rpc DownloadResults (DataRequest) returns (stream DataResult);
|
||||
}
|
||||
|
||||
message DataRequest {
|
||||
bytes value = 1;
|
||||
}
|
||||
|
||||
message DataResult {
|
||||
int32 bytes_processed = 1;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using Server;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddGrpc();
|
||||
|
||||
var app = builder.Build();
|
||||
app.MapGrpcService<DataChannelerService>();
|
||||
|
||||
app.Run();
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"profiles": {
|
||||
"Server": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:5001",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\Proto\data_channel.proto" GrpcServices="Server" Link="Protos\data_channel.proto" />
|
||||
|
||||
<PackageReference Include="Grpc.AspNetCore" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,107 @@
|
|||
#region Copyright notice and license
|
||||
|
||||
// Copyright 2019 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Threading.Channels;
|
||||
using DataChannel;
|
||||
using Grpc.Core;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class DataChannelerService : DataChanneler.DataChannelerBase
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public DataChannelerService(ILoggerFactory loggerFactory)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger<DataChannelerService>();
|
||||
}
|
||||
|
||||
public override async Task<DataResult> UploadData(
|
||||
IAsyncStreamReader<DataRequest> requestStream, ServerCallContext context)
|
||||
{
|
||||
var channel = Channel.CreateBounded<DataRequest>(new BoundedChannelOptions(capacity: 5)
|
||||
{
|
||||
SingleReader = false,
|
||||
SingleWriter = true
|
||||
});
|
||||
|
||||
var readTask = Task.Run(async () =>
|
||||
{
|
||||
await foreach (var message in requestStream.ReadAllAsync())
|
||||
{
|
||||
await channel.Writer.WriteAsync(message);
|
||||
}
|
||||
|
||||
channel.Writer.Complete();
|
||||
});
|
||||
|
||||
// Process incoming messages on three threads.
|
||||
var bytesProcessedByThread = await Task.WhenAll(
|
||||
ProcessMessagesAsync(channel.Reader, _logger),
|
||||
ProcessMessagesAsync(channel.Reader, _logger),
|
||||
ProcessMessagesAsync(channel.Reader, _logger));
|
||||
|
||||
await readTask;
|
||||
|
||||
return new DataResult { BytesProcessed = bytesProcessedByThread.Sum() };
|
||||
|
||||
static async Task<int> ProcessMessagesAsync(ChannelReader<DataRequest> reader, ILogger logger)
|
||||
{
|
||||
var total = 0;
|
||||
await foreach (var message in reader.ReadAllAsync())
|
||||
{
|
||||
total += message.Value.Length;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task DownloadResults(DataRequest request,
|
||||
IServerStreamWriter<DataResult> responseStream, ServerCallContext context)
|
||||
{
|
||||
var channel = Channel.CreateBounded<DataResult>(new BoundedChannelOptions(capacity: 5)
|
||||
{
|
||||
SingleReader = true,
|
||||
SingleWriter = false
|
||||
});
|
||||
|
||||
var consumerTask = Task.Run(async () =>
|
||||
{
|
||||
// Consume messages from channel and write to response stream.
|
||||
await foreach (var message in channel.Reader.ReadAllAsync())
|
||||
{
|
||||
await responseStream.WriteAsync(message);
|
||||
}
|
||||
});
|
||||
|
||||
var dataChunks = request.Value.Chunk(size: 10);
|
||||
|
||||
// Write messages to channel from multiple threads.
|
||||
await Task.WhenAll(dataChunks.Select(
|
||||
async c =>
|
||||
{
|
||||
var message = new DataResult { BytesProcessed = c.Length };
|
||||
await channel.Writer.WriteAsync(message);
|
||||
}));
|
||||
|
||||
// Complete writing and wait for consumer to complete.
|
||||
channel.Writer.Complete();
|
||||
await consumerTask;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Grpc": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||
|
||||
<PackageReference Include="Grpc.Net.Client" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue