Skip to content

Commit

Permalink
针对Uniapp的适配
Browse files Browse the repository at this point in the history
  • Loading branch information
fishjimi committed May 11, 2024
1 parent 0e7349e commit 1e74478
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 88 deletions.
64 changes: 7 additions & 57 deletions src/SignalR/clients/ts/signalr/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
JavaScript and TypeScript clients for SignalR for ASP.NET Core and Azure SignalR Service
JavaScript and TypeScript clients for SignalR for ASP.NET Core and Azure SignalR Service.

## Installation

```bash
npm install @microsoft/signalr
# or
yarn add @microsoft/signalr
```
Support Uniapp

To try previews of the next version, use the `next` tag on NPM:
## Installation

```bash
npm install @microsoft/signalr@next
npm install uniapp-signalr
# or
yarn add @microsoft/signalr@next
yarn add uniapp-signalr
```

## Usage
Expand All @@ -22,55 +16,11 @@ See the [SignalR Documentation](https://learn.microsoft.com/aspnet/core/signalr)

For documentation on using this client with Azure SignalR Service and Azure Functions, see the [SignalR Service serverless developer guide](https://learn.microsoft.com/azure/azure-signalr/signalr-concept-serverless-development-config).

### Browser

To use the client in a browser, copy `*.js` files from the `dist/browser` folder to your script folder include on your page using the `<script>` tag.

### WebWorker

To use the client in a webworker, copy `*.js` files from the `dist/webworker` folder to your script folder include on your webworker using the `importScripts` function. Note that webworker SignalR hub connection supports only absolute path to a SignalR hub.

### Node.js

To use the client in a NodeJS application, install the package to your `node_modules` folder and use `require('@microsoft/signalr')` to load the module. The object returned by `require('@microsoft/signalr')` has the same members as the global `signalR` object (when used in a browser).

### Example (Browser)

```javascript
let connection = new signalR.HubConnectionBuilder()
.withUrl("/chat")
.build();

connection.on("send", data => {
console.log(data);
});

connection.start()
.then(() => connection.invoke("send", "Hello"));
```

### Example (WebWorker)

```javascript
importScripts('signalr.js');

let connection = new signalR.HubConnectionBuilder()
.withUrl("https://example.com/signalr/chat")
.build();

connection.on("send", data => {
console.log(data);
});

connection.start()
.then(() => connection.invoke("send", "Hello"));

```

### Example (NodeJS)
### Example (Uniapp)

```javascript
const signalR = require("@microsoft/signalr");
import * as signalR from "uniapp-signalr";

let connection = new signalR.HubConnectionBuilder()
.withUrl("/chat")
Expand Down
15 changes: 8 additions & 7 deletions src/SignalR/clients/ts/signalr/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@microsoft/signalr",
"version": "5.0.0-dev",
"description": "ASP.NET Core SignalR Client",
"name": "uniapp-signalr",
"version": "8.0.0",
"description": "ASP.NET Core SignalR Client, Add Uniapp miniprogram support by Jimifish",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"typings": "./dist/esm/index.d.ts",
Expand All @@ -23,19 +23,20 @@
"get-version": "node -e \"const { name, version } = require('./package.json'); console.log(`${name};${version}`);\""
},
"keywords": [
"uniapp",
"signalr",
"aspnetcore"
],
"repository": {
"type": "git",
"url": "git+https://github.com/dotnet/aspnetcore.git"
"url": "git+https://github.com/fishjimi/aspnetcore.git"
},
"author": "Microsoft",
"author": "Jimifish",
"license": "MIT",
"bugs": {
"url": "https://github.com/dotnet/aspnetcore/issues"
"url": "https://github.com/fishjimi/aspnetcore/issues"
},
"homepage": "https://github.com/dotnet/aspnetcore/tree/main/src/SignalR#readme",
"homepage": "https://github.com/fishjimi/aspnetcore/tree/main/src/SignalR#readme",
"files": [
"dist/**/*",
"src/**/*"
Expand Down
5 changes: 4 additions & 1 deletion src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
import { ILogger } from "./ILogger";
import { Platform } from "./Utils";
import { XhrHttpClient } from "./XhrHttpClient";
import { UniHttpClient } from "./UniHttpClient";

/** Default implementation of {@link @microsoft/signalr.HttpClient}. */
export class DefaultHttpClient extends HttpClient {
Expand All @@ -16,7 +17,9 @@ export class DefaultHttpClient extends HttpClient {
public constructor(logger: ILogger) {
super();

if (typeof fetch !== "undefined" || Platform.isNode) {
if (Platform.isUniapp) {
this._httpClient = new UniHttpClient(logger);
} else if (typeof fetch !== "undefined" || Platform.isNode) {
this._httpClient = new FetchHttpClient(logger);
} else if (typeof XMLHttpRequest !== "undefined") {
this._httpClient = new XhrHttpClient(logger);
Expand Down
49 changes: 28 additions & 21 deletions src/SignalR/clients/ts/signalr/src/HttpConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import { ILogger, LogLevel } from "./ILogger";
import { HttpTransportType, ITransport, TransferFormat } from "./ITransport";
import { LongPollingTransport } from "./LongPollingTransport";
import { ServerSentEventsTransport } from "./ServerSentEventsTransport";
import { UniWebSocket } from "./UniWebSocket";
import { Arg, createLogger, getUserAgentHeader, Platform } from "./Utils";
import { WebSocketTransport } from "./WebSocketTransport";


/** @private */
const enum ConnectionState {
Connecting = "Connecting",
Expand Down Expand Up @@ -56,7 +58,7 @@ export class HttpConnection implements IConnection {
private transport?: ITransport;
private _startInternalPromise?: Promise<void>;
private _stopPromise?: Promise<void>;
private _stopPromiseResolver: (value?: PromiseLike<void>) => void = () => {};
private _stopPromiseResolver: (value?: PromiseLike<void>) => void = () => { };
private _stopError?: Error;
private _accessTokenFactory?: () => string | Promise<string>;
private _sendQueue?: TransportSendQueue;
Expand Down Expand Up @@ -87,7 +89,9 @@ export class HttpConnection implements IConnection {
let webSocketModule: any = null;
let eventSourceModule: any = null;

if (Platform.isNode && typeof require !== "undefined") {
if (Platform.isUniapp && !options.WebSocket) {
options.WebSocket = UniWebSocket;
} else if (Platform.isNode && typeof require !== "undefined") {
webSocketModule = getWS();
eventSourceModule = getEventSource();
}
Expand Down Expand Up @@ -308,7 +312,7 @@ export class HttpConnection implements IConnection {
}

private async _getNegotiationResponse(url: string): Promise<INegotiateResponse> {
const headers: {[k: string]: string} = {};
const headers: { [k: string]: string } = {};
const [name, value] = getUserAgentHeader();
headers[name] = value;

Expand Down Expand Up @@ -559,6 +563,10 @@ export class HttpConnection implements IConnection {
return url;
}

if (Platform.isUniapp) {
return url;
}

if (!Platform.isBrowser) {
throw new Error(`Cannot resolve '${url}'.`);
}
Expand All @@ -576,30 +584,29 @@ export class HttpConnection implements IConnection {
}

private _resolveNegotiateUrl(url: string): string {
const negotiateUrl = new URL(url);

if (negotiateUrl.pathname.endsWith('/')) {
negotiateUrl.pathname += "negotiate";
} else {
negotiateUrl.pathname += "/negotiate";
const index = url.indexOf("?");
let negotiateUrl = url.substring(0, index === -1 ? url.length : index);
if (negotiateUrl[negotiateUrl.length - 1] !== "/") {
negotiateUrl += "/";
}
const searchParams = new URLSearchParams(negotiateUrl.searchParams);
negotiateUrl += "negotiate";
negotiateUrl += index === -1 ? "" : url.substring(index);

if (!searchParams.has("negotiateVersion")) {
searchParams.append("negotiateVersion", this._negotiateVersion.toString());
if (negotiateUrl.indexOf("negotiateVersion") === -1) {
negotiateUrl += index === -1 ? "?" : "&";
negotiateUrl += "negotiateVersion=" + this._negotiateVersion;
}

if (searchParams.has("useStatefulReconnect")) {
if (searchParams.get("useStatefulReconnect") === "true") {
if (!(negotiateUrl.indexOf("useAck") === -1)) {
if (negotiateUrl.indexOf("useAck=true") > -1) {
this._options._useStatefulReconnect = true;
}
} else if (this._options._useStatefulReconnect === true) {
searchParams.append("useStatefulReconnect", "true");
negotiateUrl += index === -1 ? "?" : "&";
negotiateUrl += "useAck=true";
}

negotiateUrl.search = searchParams.toString();

return negotiateUrl.toString();
return negotiateUrl;
}
}

Expand Down Expand Up @@ -637,8 +644,8 @@ export class TransportSendQueue {
}

private _bufferData(data: string | ArrayBuffer): void {
if (this._buffer.length && typeof(this._buffer[0]) !== typeof(data)) {
throw new Error(`Expected data to be of type ${typeof(this._buffer)} but was of type ${typeof(data)}`);
if (this._buffer.length && typeof (this._buffer[0]) !== typeof (data)) {
throw new Error(`Expected data to be of type ${typeof (this._buffer)} but was of type ${typeof (data)}`);
}

this._buffer.push(data);
Expand All @@ -662,7 +669,7 @@ export class TransportSendQueue {
const transportResult = this._transportResult!;
this._transportResult = undefined;

const data = typeof(this._buffer[0]) === "string" ?
const data = typeof (this._buffer[0]) === "string" ?
this._buffer.join("") :
TransportSendQueue._concatBuffers(this._buffer);

Expand Down
1 change: 1 addition & 0 deletions src/SignalR/clients/ts/signalr/src/Uni.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare const uni: any
60 changes: 60 additions & 0 deletions src/SignalR/clients/ts/signalr/src/UniHttpClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { AbortError, HttpError } from "./Errors";
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
import { ILogger, LogLevel } from "./ILogger";

export class UniHttpClient extends HttpClient {
private readonly _logger: ILogger;

public constructor(logger: ILogger) {
super();
this._logger = logger;
}

/** @inheritDoc */
public send(request: HttpRequest): Promise<HttpResponse> {
// Check that abort was not signaled before calling send
if (request.abortSignal && request.abortSignal.aborted) {
return Promise.reject(new AbortError());
}

if (!request.method) {
return Promise.reject(new Error("No method defined."));
}
if (!request.url) {
return Promise.reject(new Error("No url defined."));
}

return new Promise<HttpResponse>((resolve, reject) => {
const temp: any = {
url: request.url,
method: request.method,
data: request.content,
dataType: 'string',
header: request.headers,
responseType: request.responseType,
success: (res: any) => {
const response: HttpResponse = new HttpResponse(res.statusCode, res.errMsg, res.data)
resolve(response)
},
fail: (res: any) => {
this._logger.log(LogLevel.Warning, `Error from HTTP request. ${res.statusCode}: ${res.errMsg}.`);
reject(new HttpError(res.errMsg, res.statusCode));
}
}
if (request.timeout) {
temp.timeout = request.timeout;
}


const requestTask = uni.request(temp);


if (request.abortSignal) {
request.abortSignal.onabort = () => {
requestTask.abort();
reject(new AbortError());
};
}
});
}
}
Loading

0 comments on commit 1e74478

Please sign in to comment.